<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Flower Crown Eevee</title>
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://eevee.cc/"/>
  <updated>2017-05-20T05:28:25.000Z</updated>
  <id>http://eevee.cc/</id>
  
  <author>
    <name>Eevee</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Use Kinect on Firefly-RK3399</title>
    <link href="http://eevee.cc/2017/05/20/use-kinect-on-firefly-rk3399/"/>
    <id>http://eevee.cc/2017/05/20/use-kinect-on-firefly-rk3399/</id>
    <published>2017-05-20T05:09:46.000Z</published>
    <updated>2017-05-20T05:28:25.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Preparation"><a href="#Preparation" class="headerlink" title="Preparation"></a>Preparation</h2>
<style type="text/css">
.post-body .fancybox img { margin: 0 auto 25px; }
</style>

<h3 id="Install-libfreenect"><a href="#Install-libfreenect" class="headerlink" title="Install libfreenect"></a>Install <a href="https://github.com/OpenKinect/libfreenect" target="_blank" rel="external">libfreenect</a></h3><blockquote>
<p>Note:<br>&nbsp;&nbsp;libfreenect  for Kinect Xbox 360<br>&nbsp;&nbsp;libfreenect2 for Kinect Xbox One</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div></pre></td><td class="code"><pre><div class="line"># download latest code, instead of latest release v0.5.5</div><div class="line">$ git clone https://github.com/OpenKinect/libfreenect.git</div><div class="line">$ cd libfreenect/</div><div class="line"></div><div class="line"># fix issue with OpenCV, in line 173</div><div class="line">$ vi OpenNI2-FreenectDriver/src/DepthStream.hpp</div><div class="line"></div><div class="line">        case XN_STREAM_PROPERTY_ZERO_PLANE_DISTANCE:    // unsigned long long or unsigned int (for OpenNI2/OpenCV)</div><div class="line">          if (*pDataSize != sizeof(unsigned long long) &amp;&amp; *pDataSize != sizeof(unsigned int))</div><div class="line">          &#123;</div><div class="line">            LogError(&quot;Unexpected size for XN_STREAM_PROPERTY_ZERO_PLANE_DISTANCE&quot;);</div><div class="line">            return ONI_STATUS_ERROR;</div><div class="line">          &#125; else &#123;</div><div class="line">            if (*pDataSize != sizeof(unsigned long long)) &#123;</div><div class="line">              *(static_cast&lt;unsigned long long*&gt;(data)) = ZERO_PLANE_DISTANCE_VAL;</div><div class="line">            &#125; else &#123;</div><div class="line">              *(static_cast&lt;unsigned int*&gt;(data)) = (unsigned int) ZERO_PLANE_DISTANCE_VAL;</div><div class="line">            &#125;</div><div class="line">          &#125;</div><div class="line">          return ONI_STATUS_OK;</div><div class="line"></div><div class="line"># build</div><div class="line">$ mkdir build</div><div class="line">$ cd build</div><div class="line">$ cmake -DBUILD_OPENNI2_DRIVER=ON ..</div><div class="line">$ make</div><div class="line"></div><div class="line"># preview</div><div class="line">$ ./bin/freenect-glview</div></pre></td></tr></table></figure>
<a id="more"></a>
<img src="/2017/05/20/use-kinect-on-firefly-rk3399/freenect-glview.png" alt="freenect-glview.png" title="">
<h3 id="Install-OpenNI"><a href="#Install-OpenNI" class="headerlink" title="Install OpenNI"></a>Install <a href="https://structure.io/openni" target="_blank" rel="external">OpenNI</a></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"># download this, aarch64 platform support</div><div class="line">$ git clone -b develop https://github.com/joinAero/OpenNI2.git</div><div class="line">$ cd OpenNI2/</div><div class="line"></div><div class="line"># deps</div><div class="line">$ sudo apt-get install libudev-dev</div><div class="line"># or, all</div><div class="line">$ sudo apt-get install \</div><div class="line">    g++              \</div><div class="line">    python           \</div><div class="line">    libusb-1.0-0-dev \</div><div class="line">    libudev-dev      \</div><div class="line">    openjdk-6-jdk    \</div><div class="line">    freeglut3-dev    \</div><div class="line">    doxygen          \</div><div class="line">    graphviz</div><div class="line"></div><div class="line"># build</div><div class="line">$ make</div><div class="line"></div><div class="line"># setup</div><div class="line">$ echo &quot;export OPENNI2_INCLUDE=`pwd`/Include&quot; &gt;&gt; ~/.bashrc</div><div class="line">$ echo &quot;export OPENNI2_REDIST=`pwd`/Bin/AArch64-Release&quot; &gt;&gt; ~/.bashrc</div></pre></td></tr></table></figure>
<p>Then, copy the freenect driver to OpenNI2 driver repository:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">$ cd libfreenect/build/</div><div class="line">$ cd lib/OpenNI2-FreenectDriver/</div><div class="line"></div><div class="line">$ export FREENECT_DRIVER_LIB=libFreenectDriver.so</div><div class="line">$ export FREENECT_DRIVER_REAL_LIB=$(python - &lt;&lt;&apos;EOF&apos;</div><div class="line">import os</div><div class="line">lib = os.environ[&apos;FREENECT_DRIVER_LIB&apos;]</div><div class="line">while os.path.islink(lib):</div><div class="line">    lib = os.readlink(lib)</div><div class="line">print(lib)</div><div class="line">EOF</div><div class="line">)</div><div class="line">$ ln -sf `pwd`/$FREENECT_DRIVER_REAL_LIB $OPENNI2_REDIST/OpenNI2/Drivers/$FREENECT_DRIVER_LIB</div></pre></td></tr></table></figure>
<!--
# ARM options: https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
# AArch64 Options: https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/AArch64-Options.html
# `cat /proc/cpuinfo`
# `lscpu`
-->
<h3 id="Build-OpenCV-with-OpenNI"><a href="#Build-OpenCV-with-OpenNI" class="headerlink" title="Build OpenCV with OpenNI"></a>Build OpenCV with OpenNI</h3><blockquote>
<p>NOTE: Please see how to <a href="http://eevee.cc/2017/05/17/build-opencv-on-firefly-rk3399/">Build OpenCV on Firefly-RK3399</a>.</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line">$ cd opencv/</div><div class="line">$ mkdir build</div><div class="line">$ cd build/</div><div class="line"></div><div class="line">$ export PY_NAME=$(python -c &apos;from sys import version_info as v; print(&quot;python%d.%d&quot; % v[:2])&apos;)</div><div class="line">$ export PY_NUMPY_DIR=$(python -c &apos;import os.path, numpy.core; print(os.path.dirname(numpy.core.__file__))&apos;)</div><div class="line"></div><div class="line">$ cmake -DCMAKE_BUILD_TYPE=RELEASE \</div><div class="line">-DCMAKE_INSTALL_PREFIX=/usr/local \</div><div class="line">\</div><div class="line">-DPYTHON2_EXECUTABLE=$(which python) \</div><div class="line">-DPYTHON_INCLUDE_DIR=/usr/include/$PY_NAME \</div><div class="line">-DPYTHON_INCLUDE_DIR2=/usr/include/aarch64-linux-gnu/$PY_NAME \</div><div class="line">-DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/lib$PY_NAME.so \</div><div class="line">-DPYTHON2_NUMPY_INCLUDE_DIRS=/usr/lib/$PY_NAME/dist-packages/numpy/core/include/ \</div><div class="line">\</div><div class="line">-DWITH_OPENNI2=ON \</div><div class="line">\</div><div class="line">-DBUILD_DOCS=OFF \</div><div class="line">-DBUILD_EXAMPLES=OFF \</div><div class="line">-DBUILD_TESTS=OFF \</div><div class="line">-DBUILD_PERF_TESTS=OFF \</div><div class="line">\</div><div class="line">-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \</div><div class="line">..</div><div class="line"></div><div class="line">$ make -j$(nproc --all)</div><div class="line">$ sudo make install</div></pre></td></tr></table></figure>
<h2 id="Usage"><a href="#Usage" class="headerlink" title="Usage"></a>Usage</h2><h3 id="C"><a href="#C" class="headerlink" title="C++"></a>C++</h3><p><code>kinect.cc</code>:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line">#include &quot;camera.hpp&quot;</div><div class="line"></div><div class="line">int main(int argc, char const *argv[]) &#123;</div><div class="line">    Camera cam(cv::CAP_OPENNI2);</div><div class="line">    if (!cam.IsOpened()) &#123;</div><div class="line">        std::cerr &lt;&lt; &quot;ERROR: Open camera failed&quot; &lt;&lt; std::endl;</div><div class="line">        return 1;</div><div class="line">    &#125;</div><div class="line">    std::cout &lt;&lt; &quot;\033[1;32mPress ESC/Q to terminate\033[0m\n\n&quot;;</div><div class="line"></div><div class="line">    double min, max;</div><div class="line">    cv::Mat adjmap, colormap;</div><div class="line">    cam.Capture([&amp;](const cv::Mat&amp; frame, const cv::Mat&amp; depthmap) &#123;</div><div class="line">        cv::minMaxIdx(depthmap, &amp;min, &amp;max);</div><div class="line">        const float scale = 255 / (max-min);</div><div class="line">        depthmap.convertTo(adjmap, CV_8UC1, scale, -min*scale);</div><div class="line"></div><div class="line">        //applyColorMap(adjmap, colormap, cv::COLORMAP_AUTUMN);</div><div class="line"></div><div class="line">        cam.DrawInfo(frame);</div><div class="line">        cam.DrawInfo(adjmap);</div><div class="line">        cv::imshow(&quot;frame&quot;, frame);</div><div class="line">        cv::imshow(&quot;depthmap&quot;, adjmap);</div><div class="line"></div><div class="line">        const int key = cv::waitKey(10);</div><div class="line">        return !(key == 27 || key == &apos;q&apos; || key == &apos;Q&apos;); // ESC/Q</div><div class="line">    &#125;);</div><div class="line"></div><div class="line">    return 0;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p><code>./build/bin/kinect</code>:</p>
<img src="/2017/05/20/use-kinect-on-firefly-rk3399/kinect-sample.png" alt="kinect-sample.png" title="">
<p>Could get complete C++ code <a href="https://gist.github.com/joinAero/40f2bf867b8d7beed2d2c5de3b6f933a" target="_blank" rel="external">here</a>, Python code <a href="https://gist.github.com/joinAero/1f76844278f141cea8338d1118423648" target="_blank" rel="external">here</a>.</p>
<blockquote>
<p>NOTE: Unable to retrieve correct image using Python code now. Please see this <a href="https://github.com/opencv/opencv/issues/4735" target="_blank" rel="external">issue</a>.</p>
</blockquote>
<h2 id="References"><a href="#References" class="headerlink" title="References"></a>References</h2><ul>
<li><a href="http://docs.opencv.org/master/d7/d6f/tutorial_kinect_openni.html" target="_blank" rel="external">Using Kinect and other OpenNI compatible depth sensors</a></li>
<li><a href="http://stackoverflow.com/questions/37946618/openni2-with-opencv-3" target="_blank" rel="external">OpenNI2 with OpenCV 3 (macOS)</a><ul>
<li>How to use Kinect using OpenNI2 with OpenCV 3 on macOS</li>
</ul>
</li>
</ul>
<h2 id="Issues"><a href="#Issues" class="headerlink" title="Issues"></a>Issues</h2><h3 id="Failed-to-use-libfreenect-form-sudo-apt-get-install-freenect"><a href="#Failed-to-use-libfreenect-form-sudo-apt-get-install-freenect" class="headerlink" title="Failed to use libfreenect form sudo apt-get install freenect"></a>Failed to use libfreenect form <code>sudo apt-get install freenect</code></h3><p><strong>Install:</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">$ sudo apt-get install freenect</div><div class="line"></div><div class="line">$ apt-cache show freenect</div><div class="line">$ dpkg -L freenect</div><div class="line">$ dpkg -L libfreenect-bin</div><div class="line">$ dpkg -L libfreenect-dev</div><div class="line">$ dpkg -L libfreenect0.5</div><div class="line">$ dpkg -L libfreenect-doc</div></pre></td></tr></table></figure>
<p><strong>Cause:</strong> not install freenect driver.</p>
<h3 id="Failed-to-build-libfreenect-on-Firefly-RK3399-aarch64"><a href="#Failed-to-build-libfreenect-on-Firefly-RK3399-aarch64" class="headerlink" title="Failed to build libfreenect on Firefly-RK3399 (aarch64)"></a>Failed to build libfreenect on Firefly-RK3399 (aarch64)</h3><p><strong>Error when build libfreenect:</strong></p>
<pre><code>[ 94%] Building CXX object OpenNI2-FreenectDriver/CMakeFiles/FreenectDriver.dir/src/ColorStream.cpp.o
In file included from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/extern/OpenNI-Linux-x64-2.2.0.33/Include/Driver/OniDriverAPI.h:24:0,
                 from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/ColorStream.hpp:6,
                 from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/ColorStream.cpp:2:
/home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/extern/OpenNI-Linux-x64-2.2.0.33/Include/OniPlatform.h:49:3: error: #error Xiron Platform Abstraction Layer - Unsupported Platform!
 # error Xiron Platform Abstraction Layer - Unsupported Platform!
   ^
In file included from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/extern/OpenNI-Linux-x64-2.2.0.33/Include/Driver/OniDriverAPI.h:25:0,
                 from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/ColorStream.hpp:6,
                 from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/ColorStream.cpp:2:
/home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/extern/OpenNI-Linux-x64-2.2.0.33/Include/OniCTypes.h:115:32: error: expected &apos;)&apos; before &apos;*&apos; token
 typedef void (ONI_CALLBACK_TYPE* OniNewFrameCallback)(OniStreamHandle stream, void* pCookie);
                                ^
...
In file included from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/ColorStream.hpp:7:0,
                 from /home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/ColorStream.cpp:2:
/home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/VideoStream.hpp: In constructor &apos;FreenectDriver::VideoStream::VideoStream(Freenect::FreenectDevice*)&apos;:
/home/firefly/Workspace/libfreenect-0.5.5/OpenNI2-FreenectDriver/src/VideoStream.hpp:34:46: error: &apos;memset&apos; was not declared in this scope
         memset(&amp;cropping, 0, sizeof(cropping));
                                              ^
OpenNI2-FreenectDriver/CMakeFiles/FreenectDriver.dir/build.make:62: recipe for target &apos;OpenNI2-FreenectDriver/CMakeFiles/FreenectDriver.dir/src/ColorStream.cpp.o&apos; failed
make[2]: *** [OpenNI2-FreenectDriver/CMakeFiles/FreenectDriver.dir/src/ColorStream.cpp.o] Error 1
CMakeFiles/Makefile2:902: recipe for target &apos;OpenNI2-FreenectDriver/CMakeFiles/FreenectDriver.dir/all&apos; failed
make[1]: *** [OpenNI2-FreenectDriver/CMakeFiles/FreenectDriver.dir/all] Error 2
Makefile:127: recipe for target &apos;all&apos; failed
make: *** [all] Error 2
</code></pre><p><strong>Case:</strong> not support aarch64 platform if build from latest release v0.5.5.</p>
<p><strong>Solution:</strong> use latest code instead of latest release v0.5.5.</p>
<p>See this commit, <a href="https://github.com/OpenKinect/libfreenect/commit/873a2cc6f625221d34856c6574a959cfe8277a1e" target="_blank" rel="external">OpenNI2: Add aarch64 platform detection</a>.</p>
<h3 id="Failed-to-use-OpenNI2-from-sudo-apt-get-install-libopenni2-dev"><a href="#Failed-to-use-OpenNI2-from-sudo-apt-get-install-libopenni2-dev" class="headerlink" title="Failed to use OpenNI2 from sudo apt-get install libopenni2-dev"></a>Failed to use OpenNI2 from <code>sudo apt-get install libopenni2-dev</code></h3><p><strong>Install:</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"># install</div><div class="line">$ sudo apt-get install libopenni2-dev</div><div class="line"></div><div class="line">$ apt-cache show libopenni2-dev</div><div class="line">$ dpkg -L libopenni2-dev</div><div class="line"></div><div class="line"># copy driver</div><div class="line">$ cd libfreenect/build/</div><div class="line">$ cd lib/OpenNI2-FreenectDriver/</div><div class="line">$ export FREENECT_DRIVER_LIB=libFreenectDriver.so</div><div class="line">$ export FREENECT_DRIVER_REAL_LIB=$(python - &lt;&lt;&apos;EOF&apos;</div><div class="line">import os</div><div class="line">lib = os.environ[&apos;FREENECT_DRIVER_LIB&apos;]</div><div class="line">while os.path.islink(lib):</div><div class="line">    lib = os.readlink(lib)</div><div class="line">print(lib)</div><div class="line">EOF</div><div class="line">)</div><div class="line">$ ln -sf `pwd`/$FREENECT_DRIVER_REAL_LIB /usr/lib/OpenNI2/Drivers/$FREENECT_DRIVER_LIB</div></pre></td></tr></table></figure>
<p><strong>Error when run sample:</strong></p>
<pre><code>OpenCV Error: Unspecified error (OpenCVKinect: Device open failed see:  DeviceOpen using default: no devices found

) in CvCapture_OpenNI2, file /home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp, line 237
VIDEOIO(cvCreateCameraCapture_OpenNI2(index)): raised OpenCV exception:

/home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp:237: error: (-2) OpenCVKinect: Device open failed see:   DeviceOpen using default: no devices found

 in function CvCapture_OpenNI2
</code></pre><p><strong>Case:</strong> not found freenect driver! why?</p>
<h3 id="Failed-to-use-OpenNI2-from-OpenNI-Linux-Arm-2-2-0-33-tar-bz2"><a href="#Failed-to-use-OpenNI2-from-OpenNI-Linux-Arm-2-2-0-33-tar-bz2" class="headerlink" title="Failed to use OpenNI2 from OpenNI-Linux-Arm-2.2.0.33.tar.bz2"></a>Failed to use OpenNI2 from <code>OpenNI-Linux-Arm-2.2.0.33.tar.bz2</code></h3><p><strong>Install:</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"># download</div><div class="line">$ curl -O https://s3.amazonaws.com/com.occipital.openni/OpenNI-Linux-Arm-2.2.0.33.tar.bz2</div><div class="line">$ tar jxf OpenNI-Linux-Arm-2.2.0.33.tar.bz2</div><div class="line">$ cd OpenNI-Linux-Arm-2.2/</div><div class="line"></div><div class="line"># install</div><div class="line">$ sudo ./install.sh</div><div class="line">$ cat OpenNIDevEnvironment &gt;&gt; ~/.bashrc</div><div class="line">$ source ~/.bashrc</div></pre></td></tr></table></figure>
<ul>
<li><a href="http://wiki.icub.org/wiki/OpenNI2" target="_blank" rel="external">OpenNI2 Wiki</a></li>
</ul>
<p>Then, copy the freenect driver to OpenNI2 driver repository:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">$ cd libfreenect/build/</div><div class="line">$ cd lib/OpenNI2-FreenectDriver/</div><div class="line"></div><div class="line">$ export FREENECT_DRIVER_LIB=libFreenectDriver.so</div><div class="line">$ export FREENECT_DRIVER_REAL_LIB=$(python - &lt;&lt;&apos;EOF&apos;</div><div class="line">import os</div><div class="line">lib = os.environ[&apos;FREENECT_DRIVER_LIB&apos;]</div><div class="line">while os.path.islink(lib):</div><div class="line">    lib = os.readlink(lib)</div><div class="line">print(lib)</div><div class="line">EOF</div><div class="line">)</div><div class="line">$ ln -sf `pwd`/$FREENECT_DRIVER_REAL_LIB $OPENNI2_REDIST/OpenNI2/Drivers/$FREENECT_DRIVER_LIB</div></pre></td></tr></table></figure>
<p><strong>Error when rebuild OpenCV:</strong></p>
<pre><code>[ 61%] Building CXX object modules/videoio/CMakeFiles/opencv_videoio.dir/src/cap_openni2.cpp.o
In file included from /home/firefly/Workspace/OpenNI-Linux-Arm-2.2/Include/OpenNI.h:24:0,
                 from /home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp:69:
/home/firefly/Workspace/OpenNI-Linux-Arm-2.2/Include/OniPlatform.h:49:3: error: #error Xiron Platform Abstraction Layer - Unsupported Platform!
 # error Xiron Platform Abstraction Layer - Unsupported Platform!
   ^
In file included from /home/firefly/Workspace/OpenNI-Linux-Arm-2.2/Include/OniCAPI.h:25:0,
                 from /home/firefly/Workspace/OpenNI-Linux-Arm-2.2/Include/OpenNI.h:28,
                 from /home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp:69:
/home/firefly/Workspace/OpenNI-Linux-Arm-2.2/Include/OniCTypes.h:115:32: error: expected &apos;)&apos; before &apos;*&apos; token
 typedef void (ONI_CALLBACK_TYPE* OniNewFrameCallback)(OniStreamHandle stream, void* pCookie);
                                ^
...
/home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp: In member function &apos;bool CvCapture_OpenNI2::setDepthGeneratorProperty(int, double)&apos;:
/home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp:612:60: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
                     if( !device.getImageRegistrationMode() == mode )
                                                            ^
modules/videoio/CMakeFiles/opencv_videoio.dir/build.make:206: recipe for target &apos;modules/videoio/CMakeFiles/opencv_videoio.dir/src/cap_openni2.cpp.o&apos; failed
make[2]: *** [modules/videoio/CMakeFiles/opencv_videoio.dir/src/cap_openni2.cpp.o] Error 1
CMakeFiles/Makefile2:3987: recipe for target &apos;modules/videoio/CMakeFiles/opencv_videoio.dir/all&apos; failed
make[1]: *** [modules/videoio/CMakeFiles/opencv_videoio.dir/all] Error 2
</code></pre><p><strong>Case:</strong> not support aarch64 platform.</p>
<p><strong>Solution:</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">$ cd OpenNI-Linux-Arm-2.2</div><div class="line"># add `__aarch64__` in line 42</div><div class="line">$ vi Include/OniPlatform.h</div><div class="line"></div><div class="line">#elif (__linux__ &amp;&amp; (__arm__ || __aarch64__))</div></pre></td></tr></table></figure>
<p><strong>Error when rebuild OpenCV again:</strong></p>
<pre><code>[ 60%] Linking CXX shared library ../../lib/libopencv_videoio.so
/usr/bin/ld: skipping incompatible /home/firefly/Workspace/OpenNI-Linux-Arm-2.2/Redist/libOpenNI2.so when searching for -lOpenNI2
/usr/bin/ld: cannot find -lOpenNI2
collect2: error: ld returned 1 exit status
modules/videoio/CMakeFiles/opencv_videoio.dir/build.make:281: recipe for target &apos;lib/libopencv_videoio.so.3.2.0&apos; failed
make[2]: *** [lib/libopencv_videoio.so.3.2.0] Error 1
CMakeFiles/Makefile2:3987: recipe for target &apos;modules/videoio/CMakeFiles/opencv_videoio.dir/all&apos; failed
make[1]: *** [modules/videoio/CMakeFiles/opencv_videoio.dir/all] Error 2
Makefile:149: recipe for target &apos;all&apos; failed
make: *** [all] Error 2
</code></pre><p><strong>Case:</strong> not incompatible “libOpenNI2.so”.</p>
<p><strong>Solution:</strong> build form source.</p>
<h3 id="Failed-to-use-libfreenect-with-OpenNI2-from-source"><a href="#Failed-to-use-libfreenect-with-OpenNI2-from-source" class="headerlink" title="Failed to use libfreenect with OpenNI2 (from source)"></a>Failed to use libfreenect with OpenNI2 (from source)</h3><p><strong>Error when run sample:</strong></p>
<pre><code>OpenNI2-FreenectDriver: (ERROR) Unexpected size for XN_STREAM_PROPERTY_ZERO_PLANE_DISTANCE
OpenCV Error: Unspecified error (CvCapture_OpenNI2::readCamerasParams : Could not read virtual plane distance!
) in readCamerasParams, file /home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp, line 404
write_register: 0x0005 &lt;= 0x00
write_register: 0x0006 &lt;= 0x00
OpenNI2-FreenectDriver: Closing device freenect://0
VIDEOIO(cvCreateCameraCapture_OpenNI2(index)): raised OpenCV exception:

/home/firefly/Workspace/opencv/modules/videoio/src/cap_openni2.cpp:404: error: (-2) CvCapture_OpenNI2::readCamerasParams : Could not read virtual plane distance!
 in function readCamerasParams
</code></pre><p><strong>Solution:</strong> fix this issue, plz see <a href="http://stackoverflow.com/questions/33657103/using-microsoft-kinect-with-opencv-3-0-0" target="_blank" rel="external">here</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Preparation&quot;&gt;&lt;a href=&quot;#Preparation&quot; class=&quot;headerlink&quot; title=&quot;Preparation&quot;&gt;&lt;/a&gt;Preparation&lt;/h2&gt;
&lt;style type=&quot;text/css&quot;&gt;
.post-body .fancybox img { margin: 0 auto 25px; }
&lt;/style&gt;

&lt;h3 id=&quot;Install-libfreenect&quot;&gt;&lt;a href=&quot;#Install-libfreenect&quot; class=&quot;headerlink&quot; title=&quot;Install libfreenect&quot;&gt;&lt;/a&gt;Install &lt;a href=&quot;https://github.com/OpenKinect/libfreenect&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;libfreenect&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;Note:&lt;br&gt;&amp;nbsp;&amp;nbsp;libfreenect  for Kinect Xbox 360&lt;br&gt;&amp;nbsp;&amp;nbsp;libfreenect2 for Kinect Xbox One&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;7&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;8&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;9&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;10&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;11&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;12&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;13&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;14&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;15&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;16&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;17&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;18&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;19&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;20&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;21&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;22&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;23&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;24&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;25&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;26&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;27&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;28&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;29&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;# download latest code, instead of latest release v0.5.5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ git clone https://github.com/OpenKinect/libfreenect.git&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ cd libfreenect/&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# fix issue with OpenCV, in line 173&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ vi OpenNI2-FreenectDriver/src/DepthStream.hpp&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;        case XN_STREAM_PROPERTY_ZERO_PLANE_DISTANCE:    // unsigned long long or unsigned int (for OpenNI2/OpenCV)&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;          if (*pDataSize != sizeof(unsigned long long) &amp;amp;&amp;amp; *pDataSize != sizeof(unsigned int))&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;          &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;            LogError(&amp;quot;Unexpected size for XN_STREAM_PROPERTY_ZERO_PLANE_DISTANCE&amp;quot;);&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;            return ONI_STATUS_ERROR;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;          &amp;#125; else &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;            if (*pDataSize != sizeof(unsigned long long)) &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;              *(static_cast&amp;lt;unsigned long long*&amp;gt;(data)) = ZERO_PLANE_DISTANCE_VAL;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;            &amp;#125; else &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;              *(static_cast&amp;lt;unsigned int*&amp;gt;(data)) = (unsigned int) ZERO_PLANE_DISTANCE_VAL;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;            &amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;          &amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;          return ONI_STATUS_OK;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# build&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ mkdir build&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ cd build&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ cmake -DBUILD_OPENNI2_DRIVER=ON ..&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ make&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# preview&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ ./bin/freenect-glview&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="OpenCV" scheme="http://eevee.cc/tags/OpenCV/"/>
    
      <category term="Firefly-RK3399" scheme="http://eevee.cc/tags/Firefly-RK3399/"/>
    
      <category term="OpenNI2" scheme="http://eevee.cc/tags/OpenNI2/"/>
    
      <category term="libfreenect" scheme="http://eevee.cc/tags/libfreenect/"/>
    
  </entry>
  
  <entry>
    <title>Build OpenCV on Firefly-RK3399</title>
    <link href="http://eevee.cc/2017/05/17/build-opencv-on-firefly-rk3399/"/>
    <id>http://eevee.cc/2017/05/17/build-opencv-on-firefly-rk3399/</id>
    <published>2017-05-17T04:49:56.000Z</published>
    <updated>2017-05-20T05:10:31.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Install"><a href="#Install" class="headerlink" title="Install"></a>Install</h2><h3 id="Required-Packages"><a href="#Required-Packages" class="headerlink" title="Required Packages"></a>Required Packages</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"># compiler ✓</div><div class="line">$ sudo apt-get install build-essential</div><div class="line"># required ✓</div><div class="line">$ sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev</div><div class="line"></div><div class="line"># optional ✓</div><div class="line">$ sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev</div></pre></td></tr></table></figure>
<h3 id="Getting-OpenCV-Source-Code"><a href="#Getting-OpenCV-Source-Code" class="headerlink" title="Getting OpenCV Source Code"></a>Getting OpenCV Source Code</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ git clone https://github.com/opencv/opencv.git</div><div class="line">$ cd opencv/</div><div class="line">$ git checkout 3.2.0</div></pre></td></tr></table></figure>
<p>If use extra modules:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ git clone https://github.com/opencv/opencv_contrib.git</div><div class="line">$ cd opencv_contrib/</div><div class="line">$ git checkout 3.2.0</div></pre></td></tr></table></figure>
<h3 id="Building-OpenCV-from-Source"><a href="#Building-OpenCV-from-Source" class="headerlink" title="Building OpenCV from Source"></a>Building OpenCV from Source</h3><a id="more"></a>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line">$ cd opencv/</div><div class="line">$ mkdir build</div><div class="line">$ cd build/</div><div class="line"></div><div class="line">$ export PY_NAME=$(python -c &apos;from sys import version_info as v; print(&quot;python%d.%d&quot; % v[:2])&apos;)</div><div class="line">$ export PY_NUMPY_DIR=$(python -c &apos;import os.path, numpy.core; print(os.path.dirname(numpy.core.__file__))&apos;)</div><div class="line"></div><div class="line">$ cmake -DCMAKE_BUILD_TYPE=RELEASE \</div><div class="line">-DCMAKE_INSTALL_PREFIX=/usr/local \</div><div class="line">\</div><div class="line">-DPYTHON2_EXECUTABLE=$(which python) \</div><div class="line">-DPYTHON_INCLUDE_DIR=/usr/include/$PY_NAME \</div><div class="line">-DPYTHON_INCLUDE_DIR2=/usr/include/aarch64-linux-gnu/$PY_NAME \</div><div class="line">-DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/lib$PY_NAME.so \</div><div class="line">-DPYTHON2_NUMPY_INCLUDE_DIRS=/usr/lib/$PY_NAME/dist-packages/numpy/core/include/ \</div><div class="line">\</div><div class="line">-DBUILD_DOCS=OFF \</div><div class="line">-DBUILD_EXAMPLES=OFF \</div><div class="line">-DBUILD_TESTS=OFF \</div><div class="line">-DBUILD_PERF_TESTS=OFF \</div><div class="line">\</div><div class="line">-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \</div><div class="line">..</div><div class="line"></div><div class="line">$ make -j$(nproc --all)</div><div class="line">$ sudo make install</div></pre></td></tr></table></figure>
<!--
$ cmake ... \
-DWITH_V4L=ON \
-DWITH_LIBV4L=ON \
...

--     V4L/V4L2:                    Using libv4l1 (ver 1.10.0) / libv4l2 (ver 1.10.0)
-->
<p><strong><code>cmake</code> result:</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div></pre></td><td class="code"><pre><div class="line">-- General configuration for OpenCV 3.2.0 =====================================</div><div class="line">--   Version control:               3.2.0</div><div class="line">--</div><div class="line">--   Extra modules:</div><div class="line">--     Location (extra):            /home/firefly/Workspace/opencv_contrib/modules</div><div class="line">--     Version control (extra):     3.2.0</div><div class="line">--</div><div class="line">--   Platform:</div><div class="line">--     Timestamp:                   2017-05-13T13:43:22Z</div><div class="line">--     Host:                        Linux 4.4.16 aarch64</div><div class="line">--     CMake:                       3.5.1</div><div class="line">--     CMake generator:             Unix Makefiles</div><div class="line">--     CMake build tool:            /usr/bin/make</div><div class="line">--     Configuration:               RELEASE</div><div class="line">--</div><div class="line">--   C/C++:</div><div class="line">--     Built as dynamic libs?:      YES</div><div class="line">--     C++ Compiler:                /usr/bin/c++  (ver 5.4.0)</div><div class="line">--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG</div><div class="line">--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG</div><div class="line">--     C Compiler:                  /usr/bin/cc</div><div class="line">--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG</div><div class="line">--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG</div><div class="line">--     Linker flags (Release):</div><div class="line">--     Linker flags (Debug):</div><div class="line">--     ccache:                      NO</div><div class="line">--     Precompiled headers:         YES</div><div class="line">--     Extra dependencies:          /usr/lib/aarch64-linux-gnu/libpng.so /usr/lib/aarch64-linux-gnu/libz.so /usr/lib/aarch64-linux-gnu/libtiff.so /usr/lib/aarch64-linux-gnu/libjasper.so /usr/lib/aarch64-linux-gnu/libjpeg.so gtk-x11-2.0 gdk-x11-2.0 pangocairo-1.0 atk-1.0 cairo gdk_pixbuf-2.0 gio-2.0 pangoft2-1.0 pango-1.0 gobject-2.0 glib-2.0 fontconfig freetype gthread-2.0 dc1394 avcodec-ffmpeg avformat-ffmpeg avutil-ffmpeg swscale-ffmpeg dl m pthread rt</div><div class="line">--     3rdparty dependencies:       libwebp IlmImf tegra_hal</div><div class="line">--</div><div class="line">--   OpenCV modules:</div><div class="line">--     To be built:                 core flann imgproc ml photo reg surface_matching video freetype fuzzy imgcodecs shape videoio highgui objdetect plot superres xobjdetect xphoto bgsegm bioinspired dpm face features2d line_descriptor saliency text calib3d ccalib datasets rgbd stereo videostab xfeatures2d ximgproc aruco optflow phase_unwrapping stitching structured_light python2</div><div class="line">--     Disabled:                    world contrib_world</div><div class="line">--     Disabled by dependency:      tracking</div><div class="line">--     Unavailable:                 cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java python3 ts viz cnn_3dobj cvv dnn hdf matlab sfm</div><div class="line">--</div><div class="line">--   GUI:</div><div class="line">--     QT:                          NO</div><div class="line">--     GTK+ 2.x:                    YES (ver 2.24.30)</div><div class="line">--     GThread :                    YES (ver 2.48.2)</div><div class="line">--     GtkGlExt:                    NO</div><div class="line">--     OpenGL support:              NO</div><div class="line">--     VTK support:                 NO</div><div class="line">--</div><div class="line">--   Media I/O:</div><div class="line">--     ZLib:                        /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.8)</div><div class="line">--     JPEG:                        /usr/lib/aarch64-linux-gnu/libjpeg.so (ver )</div><div class="line">--     WEBP:                        build (ver 0.3.1)</div><div class="line">--     PNG:                         /usr/lib/aarch64-linux-gnu/libpng.so (ver 1.2.54)</div><div class="line">--     TIFF:                        /usr/lib/aarch64-linux-gnu/libtiff.so (ver 42 - 4.0.6)</div><div class="line">--     JPEG 2000:                   /usr/lib/aarch64-linux-gnu/libjasper.so (ver 1.900.1)</div><div class="line">--     OpenEXR:                     build (ver 1.7.1)</div><div class="line">--     GDAL:                        NO</div><div class="line">--     GDCM:                        NO</div><div class="line">--</div><div class="line">--   Video I/O:</div><div class="line">--     DC1394 1.x:                  NO</div><div class="line">--     DC1394 2.x:                  YES (ver 2.2.4)</div><div class="line">--     FFMPEG:                      YES</div><div class="line">--       avcodec:                   YES (ver 56.60.100)</div><div class="line">--       avformat:                  YES (ver 56.40.101)</div><div class="line">--       avutil:                    YES (ver 54.31.100)</div><div class="line">--       swscale:                   YES (ver 3.1.101)</div><div class="line">--       avresample:                NO</div><div class="line">--     GStreamer:                   NO</div><div class="line">--     OpenNI:                      NO</div><div class="line">--     OpenNI PrimeSensor Modules:  NO</div><div class="line">--     OpenNI2:                     NO</div><div class="line">--     PvAPI:                       NO</div><div class="line">--     GigEVisionSDK:               NO</div><div class="line">--     Aravis SDK:                  NO</div><div class="line">--     UniCap:                      NO</div><div class="line">--     UniCap ucil:                 NO</div><div class="line">--     V4L/V4L2:                    NO/YES</div><div class="line">--     XIMEA:                       NO</div><div class="line">--     Xine:                        NO</div><div class="line">--     gPhoto2:                     NO</div><div class="line">--</div><div class="line">--   Parallel framework:            pthreads</div><div class="line">--</div><div class="line">--   Other third-party libraries:</div><div class="line">--     Use IPP:                     NO</div><div class="line">--     Use VA:                      NO</div><div class="line">--     Use Intel VA-API/OpenCL:     NO</div><div class="line">--     Use Lapack:                  NO</div><div class="line">--     Use Eigen:                   NO</div><div class="line">--     Use Cuda:                    NO</div><div class="line">--     Use OpenCL:                  YES</div><div class="line">--     Use OpenVX:                  NO</div><div class="line">--     Use custom HAL:              YES (carotene (ver 0.0.1))</div><div class="line">--</div><div class="line">--   OpenCL:                        &lt;Dynamic loading of OpenCL library&gt;</div><div class="line">--     Include path:                /home/firefly/Workspace/opencv/3rdparty/include/opencl/1.2</div><div class="line">--     Use AMDFFT:                  NO</div><div class="line">--     Use AMDBLAS:                 NO</div><div class="line">--</div><div class="line">--   Python 2:</div><div class="line">--     Interpreter:                 /usr/bin/python (ver 2.7.12)</div><div class="line">--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython2.7.so (ver 2.7.12)</div><div class="line">--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include/ (ver 1.11.0)</div><div class="line">--     packages path:               lib/python2.7/dist-packages</div><div class="line">--</div><div class="line">--   Python 3:</div><div class="line">--     Interpreter:                 /usr/bin/python3 (ver 3.5.2)</div><div class="line">--</div><div class="line">--   Python (for build):            /usr/bin/python</div><div class="line">--</div><div class="line">--   Java:</div><div class="line">--     ant:                         NO</div><div class="line">--     JNI:                         NO</div><div class="line">--     Java wrappers:               NO</div><div class="line">--     Java tests:                  NO</div><div class="line">--</div><div class="line">--   Matlab:                        Matlab not found or implicitly disabled</div><div class="line">--</div><div class="line">--   Tests and samples:</div><div class="line">--     Tests:                       NO</div><div class="line">--     Performance tests:           NO</div><div class="line">--     C/C++ Examples:              NO</div><div class="line">--</div><div class="line">--   Install path:                  /usr/local</div><div class="line">--</div><div class="line">--   cvconfig.h is in:              /home/firefly/Workspace/opencv/build</div><div class="line">-- -----------------------------------------------------------------</div></pre></td></tr></table></figure>
<h3 id="Extra-Links"><a href="#Extra-Links" class="headerlink" title="Extra Links"></a>Extra Links</h3><ul>
<li><a href="http://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html" target="_blank" rel="external">Installation in Linux</a></li>
</ul>
<h2 id="Examples"><a href="#Examples" class="headerlink" title="Examples"></a>Examples</h2><h3 id="Canny-Edge-Detection"><a href="#Canny-Edge-Detection" class="headerlink" title="Canny Edge Detection"></a><a href="http://docs.opencv.org/master/da/d22/tutorial_py_canny.html" target="_blank" rel="external">Canny Edge Detection</a></h3><p><code>canny.py</code>:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">#!/usr/bin/env python</div><div class="line"></div><div class="line">import cv2</div><div class="line">import numpy as np</div><div class="line"></div><div class="line">def main():</div><div class="line">    img = cv2.imread(&apos;../data/messi5.jpg&apos;, 0)</div><div class="line">    edges = cv2.Canny(img, 100, 200)</div><div class="line"></div><div class="line">    cv2.imshow(&apos;Original &amp; Edge&apos;, np.vstack((img, edges)))</div><div class="line">    cv2.waitKey()</div><div class="line">    cv2.destroyAllWindows()</div><div class="line"></div><div class="line">if __name__ == &apos;__main__&apos;:</div><div class="line">    main()</div></pre></td></tr></table></figure>
<img src="/2017/05/17/build-opencv-on-firefly-rk3399/canny.png" alt="canny.png" title="">
<h2 id="Appendix"><a href="#Appendix" class="headerlink" title="Appendix"></a>Appendix</h2><h3 id="Install-pip"><a href="#Install-pip" class="headerlink" title="Install pip"></a>Install <a href="https://pip.pypa.io/en/stable/installing/" target="_blank" rel="external">pip</a></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">$ python --version</div><div class="line">Python 2.7.12</div><div class="line"></div><div class="line">$ curl -O https://bootstrap.pypa.io/get-pip.py</div><div class="line">$ python get-pip.py</div><div class="line"></div><div class="line">$ vi ~/.pip/pip.conf</div><div class="line">[global]</div><div class="line">format=columns</div><div class="line">index-url=http://mirrors.aliyun.com/pypi/simple/</div><div class="line">[install]</div><div class="line">trusted-host=mirrors.aliyun.com</div></pre></td></tr></table></figure>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Install&quot;&gt;&lt;a href=&quot;#Install&quot; class=&quot;headerlink&quot; title=&quot;Install&quot;&gt;&lt;/a&gt;Install&lt;/h2&gt;&lt;h3 id=&quot;Required-Packages&quot;&gt;&lt;a href=&quot;#Required-Packages&quot; class=&quot;headerlink&quot; title=&quot;Required Packages&quot;&gt;&lt;/a&gt;Required Packages&lt;/h3&gt;&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;7&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;# compiler ✓&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ sudo apt-get install build-essential&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# required ✓&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# optional ✓&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&quot;Getting-OpenCV-Source-Code&quot;&gt;&lt;a href=&quot;#Getting-OpenCV-Source-Code&quot; class=&quot;headerlink&quot; title=&quot;Getting OpenCV Source Code&quot;&gt;&lt;/a&gt;Getting OpenCV Source Code&lt;/h3&gt;&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ git clone https://github.com/opencv/opencv.git&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ cd opencv/&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ git checkout 3.2.0&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;If use extra modules:&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ git clone https://github.com/opencv/opencv_contrib.git&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ cd opencv_contrib/&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ git checkout 3.2.0&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&quot;Building-OpenCV-from-Source&quot;&gt;&lt;a href=&quot;#Building-OpenCV-from-Source&quot; class=&quot;headerlink&quot; title=&quot;Building OpenCV from Source&quot;&gt;&lt;/a&gt;Building OpenCV from Source&lt;/h3&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="OpenCV" scheme="http://eevee.cc/tags/OpenCV/"/>
    
      <category term="Firefly-RK3399" scheme="http://eevee.cc/tags/Firefly-RK3399/"/>
    
  </entry>
  
  <entry>
    <title>Headless Firefly-RK3399 Setup</title>
    <link href="http://eevee.cc/2017/05/10/headless-firefly-rk3399-setup/"/>
    <id>http://eevee.cc/2017/05/10/headless-firefly-rk3399-setup/</id>
    <published>2017-05-10T13:40:10.000Z</published>
    <updated>2017-05-17T04:20:47.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Firefly-RK3399"><a href="#Firefly-RK3399" class="headerlink" title="Firefly-RK3399"></a><a href="http://www.t-firefly.com/zh/firenow/Firefly-rk3399/" target="_blank" rel="external">Firefly-RK3399</a></h1>
<style type="text/css">
.post-body li p { margin: 0; }
.post-body .fancybox img { margin: 0 auto; }
.post-body li .fancybox img { margin: 25px auto; }
.post-body .code {
  font-family: consolas, Menlo, "PingFang SC", "Microsoft YaHei", monospace;
  padding: 2px 4px;
  word-wrap: break-word;
  color: #555;
  background: #eee;
  border-radius: 3px;
  font-size: 13px;
}
</style>

<h2 id="Flash-Image"><a href="#Flash-Image" class="headerlink" title="Flash Image"></a><a href="http://wiki.t-firefly.com/index.php/Firefly-RK3399/Flash_image/en" target="_blank" rel="external">Flash Image</a></h2><p>Windows:</p>
<ol>
<li>Download <a href="http://en.t-firefly.com/en/firenow/Firefly_RK3399/download/" target="_blank" rel="external">here</a>, 或<a href="http://www.t-firefly.com/zh/firenow/Firefly-rk3399/download/" target="_blank" rel="external">这里</a><ul>
<li>Ubuntu 16.04 image: Firefly-RK3399_Ubuntu16.04_201703181519.img</li>
<li>RK Tool: AndroidTool_Release_v2.38.rar</li>
<li>RK USB driver: DriverAssitant_v4.5.rar</li>
</ul>
</li>
<li><p>Install RK USB Driver</p>
<ul>
<li><p>Run “DriverAssitant_v4.5/DriverInstall.exe”</p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/install-rk-usb-driver.png" alt="install-rk-usb-driver.png" title="">
</li>
</ul>
</li>
<li><p>Connect device to host</p>
<ol>
<li>Connect the power adapter to board.</li>
<li>Use Type-C cable to connect host and device together.</li>
<li>Press and hold RECOVERY key.</li>
<li>Shortly press RESET key.</li>
<li><p>After around two seconds, release RECOVERY key.</p>
<a id="more"></a>
<p>The host will prompt to have new device detected and configured. Open the Device Management, you’ll find a new device name “Rockusb Device”, as shown below. Return to previous step to reinstall driver if it is not shown.</p>
<img src="/2017/05/10/headless-firefly-rk3399-setup/rk-usb-device-detected.png" alt="rk-usb-device-detected.png" title="">
</li>
</ol>
</li>
<li><p>Flush image</p>
<ol>
<li><p>Run “AndroidTool_Release_v2.38/AndroidTool.exe” as Administrator.</p>
<ul>
<li><p>Edit “config.ini”, set “Selected=2” to English</p>
<img src="/2017/05/10/headless-firefly-rk3399-setup/android-tool.png" alt="android-tool.png" title="">
</li>
</ul>
</li>
<li><p>Switch to “Upgrade Firmware” tab page.</p>
</li>
<li>Click “Firmware” button and open the image file.<ul>
<li>Detail information of the image file, like version and chip, is shown.</li>
</ul>
</li>
<li><p>Click “Upgrade” button to start flash.</p>
 <img src="/2017/05/10/headless-firefly-rk3399-setup/upgrade-firmware.png" alt="upgrade-firmware.png" title="">
</li>
<li><p>If upgrade fails, please try “LowerFormat” in the “Download Image” tab page first, then try again.</p>
<blockquote>
<p>WARN: If you flash firmware laoder different version of the original machine, please click “Erase Flash” before upgrading the firmware.</p>
</blockquote>
</li>
</ol>
</li>
</ol>
<h2 id="Setup-Firefly"><a href="#Setup-Firefly" class="headerlink" title="Setup Firefly"></a>Setup Firefly</h2><ol>
<li>Connect Display or TV with HDMI cable</li>
<li>Connect the power adapter to the board<ul>
<li>The board will boot automatically once power on</li>
</ul>
</li>
<li>Plug USB mouse &amp; keyboard to the board</li>
</ol>
<p>Now, you can control the board.</p>
<pre><code>Username: firefly
Password: firefly
</code></pre><ol>
<li>Connect the Wi-Fi</li>
<li>Enable SSH server<ul>
<li>Detect SSH server, <code>ps aux | grep sshd</code><ul>
<li>Otherwise, <code>sudo apt-get install openssh-server</code> and <code>sudo /etc/init.d/ssh start</code></li>
</ul>
</li>
<li>Get ip address, <code>ifconfig | grep &quot;inet &quot;</code></li>
<li>SSH from remote pc, <code>ssh firefly@&lt;ip&gt;</code></li>
</ul>
</li>
<li><p>Screen Sharing from Firefly</p>
<ul>
<li>Install, <code>sudo apt-get install vino</code></li>
<li><p>Config, <span class="code">vino-preferences</span></p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/vino-preferences.png" alt="vino-preferences.png" title="">
</li>
<li><p>Start, <span class="code">/usr/lib/vino/vino-server –sm-disable`</span></p>
</li>
<li><p>Autostart, open “Session and Startup” and check “Desktop Sharing”,</p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/startup.png" alt="startup.png" title="">
</li>
</ul>
</li>
<li><p>Remote access from Ubuntu</p>
<ul>
<li><p>Open “Remmina Remote Desktop Client” and add connection,</p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/remote-desktop-client.png" alt="remote-desktop-client.png" title="">
</li>
<li><p>Or, remote access from Mac, plz see <a href="/2017/05/09/screen-sharing-from-ubuntu-to-mac/">here</a>.</p>
</li>
</ul>
</li>
</ol>
<p><strong>Finally, you can control the board from remote PC, without extra accessories or devices.</strong></p>
<blockquote>
<p>NOTE: You could get ip address of the board from your router’s home page.</p>
</blockquote>
<p><strong>If you wanna access the Firefly’s files, you can do as follows:</strong></p>
<ol>
<li><p>Install <a href="https://www.samba.org/" target="_blank" rel="external">Samba</a> on Firefly,</p>
 <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"># samba</div><div class="line">sudo apt-get install samba samba-common-bin</div><div class="line"></div><div class="line"># config samba</div><div class="line">sudo vi /etc/samba/smb.conf</div><div class="line"></div><div class="line">[homes]</div><div class="line">  read only = no</div><div class="line"></div><div class="line"># restart</div><div class="line">sudo /etc/init.d/samba restart</div><div class="line"># add user</div><div class="line">sudo smbpasswd -a firefly</div></pre></td></tr></table></figure>
</li>
<li><p>Open “Finder” on Mac,</p>
<ul>
<li><p>“Go &gt; Connect to Server”</p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/smb-connect.png" alt="smb-connect.png" title="">
</li>
<li><p>Then, select “firefly” volume</p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/smb-access.png" alt="smb-access.png" title="">
</li>
</ul>
</li>
</ol>
<p><strong>If you wanna setup other WiFi connections, you can do as follows:</strong></p>
<ol>
<li><p>Add a WiFi connection,</p>
<ul>
<li><p>Run <span class="code">nmtui</span>, then “Edit a connection &gt; Add &gt; Wi-Fi”</p>
  <img src="/2017/05/10/headless-firefly-rk3399-setup/nmtui.png" alt="nmtui.png" title="">
</li>
<li><p>Field “Device” is “wlan0 mac address”, run <code>ip addr</code> to get</p>
</li>
<li>Enter “OK”, done</li>
</ul>
</li>
<li><p>Connection file is created here,</p>
 <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ll /etc/NetworkManager/system-connections/</div></pre></td></tr></table></figure>
</li>
<li><p>Connect a WiFi with SSID found nearby,</p>
 <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ nmcli device wifi con &quot;ssid&quot; password &quot;password&quot;</div></pre></td></tr></table></figure>
</li>
</ol>
]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;Firefly-RK3399&quot;&gt;&lt;a href=&quot;#Firefly-RK3399&quot; class=&quot;headerlink&quot; title=&quot;Firefly-RK3399&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://www.t-firefly.com/zh/firenow/Firefly-rk3399/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Firefly-RK3399&lt;/a&gt;&lt;/h1&gt;
&lt;style type=&quot;text/css&quot;&gt;
.post-body li p { margin: 0; }
.post-body .fancybox img { margin: 0 auto; }
.post-body li .fancybox img { margin: 25px auto; }
.post-body .code {
  font-family: consolas, Menlo, &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, monospace;
  padding: 2px 4px;
  word-wrap: break-word;
  color: #555;
  background: #eee;
  border-radius: 3px;
  font-size: 13px;
}
&lt;/style&gt;

&lt;h2 id=&quot;Flash-Image&quot;&gt;&lt;a href=&quot;#Flash-Image&quot; class=&quot;headerlink&quot; title=&quot;Flash Image&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://wiki.t-firefly.com/index.php/Firefly-RK3399/Flash_image/en&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Flash Image&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Windows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download &lt;a href=&quot;http://en.t-firefly.com/en/firenow/Firefly_RK3399/download/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;here&lt;/a&gt;, 或&lt;a href=&quot;http://www.t-firefly.com/zh/firenow/Firefly-rk3399/download/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;这里&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;Ubuntu 16.04 image: Firefly-RK3399_Ubuntu16.04_201703181519.img&lt;/li&gt;
&lt;li&gt;RK Tool: AndroidTool_Release_v2.38.rar&lt;/li&gt;
&lt;li&gt;RK USB driver: DriverAssitant_v4.5.rar&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install RK USB Driver&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run “DriverAssitant_v4.5/DriverInstall.exe”&lt;/p&gt;
  &lt;img src=&quot;/2017/05/10/headless-firefly-rk3399-setup/install-rk-usb-driver.png&quot; alt=&quot;install-rk-usb-driver.png&quot; title=&quot;&quot;&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect device to host&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Connect the power adapter to board.&lt;/li&gt;
&lt;li&gt;Use Type-C cable to connect host and device together.&lt;/li&gt;
&lt;li&gt;Press and hold RECOVERY key.&lt;/li&gt;
&lt;li&gt;Shortly press RESET key.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After around two seconds, release RECOVERY key.&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="Screen Sharing" scheme="http://eevee.cc/tags/Screen-Sharing/"/>
    
      <category term="Ubuntu" scheme="http://eevee.cc/tags/Ubuntu/"/>
    
      <category term="Firefly-RK3399" scheme="http://eevee.cc/tags/Firefly-RK3399/"/>
    
  </entry>
  
  <entry>
    <title>Screen Sharing from Ubuntu to Mac</title>
    <link href="http://eevee.cc/2017/05/09/screen-sharing-from-ubuntu-to-mac/"/>
    <id>http://eevee.cc/2017/05/09/screen-sharing-from-ubuntu-to-mac/</id>
    <published>2017-05-09T09:00:45.000Z</published>
    <updated>2017-07-04T08:06:44.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Ubuntu"><a href="#Ubuntu" class="headerlink" title="Ubuntu"></a>Ubuntu</h2>
<style type="text/css">
.post-body .fancybox img { margin: 0 auto 25px; }
</style>

<p>1) Open “Desktop Sharing” and setup,</p>
<img src="/2017/05/09/screen-sharing-from-ubuntu-to-mac/desktop-sharing.png" alt="desktop-sharing.png" title="">
<p>2) <code>sudo apt-get install dconf-tools</code> and run <code>dconf-editor</code>,</p>
<img src="/2017/05/09/screen-sharing-from-ubuntu-to-mac/dconf-editor.png" alt="dconf-editor.png" title="">
<p>Or,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ export DISPLAY=:0</div><div class="line">$ dconf write /org/gnome/desktop/remote-access/require-encryption false</div></pre></td></tr></table></figure>
<h2 id="Mac"><a href="#Mac" class="headerlink" title="Mac"></a>Mac</h2><p>1) Spotlight Search “Screen Sharing” and connect to,</p>
<a id="more"></a>
<img src="/2017/05/09/screen-sharing-from-ubuntu-to-mac/screen-sharing.png" alt="screen-sharing.png" title="">
<p>2) View and control “Ubuntu Desktop”,</p>
<img src="/2017/05/09/screen-sharing-from-ubuntu-to-mac/ubuntu-desktop.png" alt="ubuntu-desktop.png" title="">
<h2 id="References"><a href="#References" class="headerlink" title="References"></a>References</h2><ul>
<li><a href="https://askubuntu.com/questions/463486/can-no-longer-use-screen-share-to-connect-mac-to-ubuntu-since-upgrading-to-14-04" target="_blank" rel="external">Can no longer use Screen Share …</a></li>
<li><a href="https://unix.stackexchange.com/questions/73041/enable-remote-desktop-for-gnome-from-command-line" target="_blank" rel="external">Enable remote desktop for Gnome from command line?</a></li>
</ul>
<!--

Alternatives (failed):

<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"># 1) Ubuntu:</div><div class="line"></div><div class="line">$ sudo vi /etc/ssh/sshd_config</div><div class="line">X11Forwarding yes</div><div class="line"></div><div class="line">$ sudo service ssh restart</div><div class="line"></div><div class="line"># 2) Mac:</div><div class="line"></div><div class="line"># XQuartz: https://www.xquartz.org/</div><div class="line">$ brew install Caskroom/cask/xquartz</div><div class="line"></div><div class="line"># 3) XQuartz:</div><div class="line"></div><div class="line"># SSH denied</div><div class="line">$ sudo vi /etc/ssh/ssh_config</div><div class="line">Host *</div><div class="line">    ForwardAgent yes</div><div class="line">    ForwardX11 yes</div><div class="line">$ ssh -X &lt;user@host&gt;</div><div class="line"></div><div class="line"># Remote Desktop from Mac to Ubuntu</div><div class="line">$ Xnest -geometry 1280x800 :1 &amp; DISPLAY=:1 ssh -Y &lt;user@host&gt; gnome-session</div></pre></td></tr></table></figure>
<p>But,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">Warning: No xauth data; using fake authentication data for X11 forwarding.</div><div class="line">Assertion failed: (key-&gt;initialized), function dixGetPrivateAddr, file ../include/privates.h, line 122.</div><div class="line">connect /tmp/.X11-unix/X1: Connection refused</div><div class="line">connect /tmp/.X11-unix/X1: Connection refused</div><div class="line"></div><div class="line">** (gnome-session:4546): WARNING **: Could not open X display</div><div class="line">connect /tmp/.X11-unix/X1: Connection refused</div><div class="line">connect /tmp/.X11-unix/X1: Connection refused</div><div class="line">connect /tmp/.X11-unix/X1: Connection refused</div><div class="line">connect /tmp/.X11-unix/X1: Connection refused</div><div class="line"></div><div class="line">** (gnome-session:4546): WARNING **: Cannot open display:</div><div class="line">[1]+  Abort trap: 6           Xnest -geometry 1280x800 :1</div></pre></td></tr></table></figure>
<p>–&gt;</p>
-->]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Ubuntu&quot;&gt;&lt;a href=&quot;#Ubuntu&quot; class=&quot;headerlink&quot; title=&quot;Ubuntu&quot;&gt;&lt;/a&gt;Ubuntu&lt;/h2&gt;
&lt;style type=&quot;text/css&quot;&gt;
.post-body .fancybox img { margin: 0 auto 25px; }
&lt;/style&gt;

&lt;p&gt;1) Open “Desktop Sharing” and setup,&lt;/p&gt;
&lt;img src=&quot;/2017/05/09/screen-sharing-from-ubuntu-to-mac/desktop-sharing.png&quot; alt=&quot;desktop-sharing.png&quot; title=&quot;&quot;&gt;
&lt;p&gt;2) &lt;code&gt;sudo apt-get install dconf-tools&lt;/code&gt; and run &lt;code&gt;dconf-editor&lt;/code&gt;,&lt;/p&gt;
&lt;img src=&quot;/2017/05/09/screen-sharing-from-ubuntu-to-mac/dconf-editor.png&quot; alt=&quot;dconf-editor.png&quot; title=&quot;&quot;&gt;
&lt;p&gt;Or,&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ export DISPLAY=:0&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ dconf write /org/gnome/desktop/remote-access/require-encryption false&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;Mac&quot;&gt;&lt;a href=&quot;#Mac&quot; class=&quot;headerlink&quot; title=&quot;Mac&quot;&gt;&lt;/a&gt;Mac&lt;/h2&gt;&lt;p&gt;1) Spotlight Search “Screen Sharing” and connect to,&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="Screen Sharing" scheme="http://eevee.cc/tags/Screen-Sharing/"/>
    
      <category term="Remote Desktop" scheme="http://eevee.cc/tags/Remote-Desktop/"/>
    
      <category term="Ubuntu" scheme="http://eevee.cc/tags/Ubuntu/"/>
    
      <category term="Mac" scheme="http://eevee.cc/tags/Mac/"/>
    
  </entry>
  
  <entry>
    <title>Headless Raspberry Pi Setup</title>
    <link href="http://eevee.cc/2017/05/09/headless-raspberry-pi-setup/"/>
    <id>http://eevee.cc/2017/05/09/headless-raspberry-pi-setup/</id>
    <published>2017-05-09T01:12:33.000Z</published>
    <updated>2017-05-11T01:25:04.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Install"><a href="#Install" class="headerlink" title="Install"></a>Install</h2>
<style type="text/css">
.post-body li p { margin: 0; }
</style>

<ol>
<li><a href="https://www.raspberrypi.org/downloads/raspbian/" target="_blank" rel="external">Download</a> “RASPBIAN JESSIE LITE” without PIXEL desktop.</li>
<li>Unzip it to get the image file (.img) for writing to your SD card.</li>
<li><p>Setup headless settings, <strong>if don’t have an extra keyboard or HDMI cable</strong>.</p>
<ol>
<li>Add “ssh” file to the SD card root. Then boot your Pi.</li>
<li>Connect it to the router with wire. Then get its ip from the router.</li>
<li>Use SSH to connect to your Pi.<ul>
<li><code>ssh pi@&lt;IP&gt;</code>, password: raspberry.</li>
</ul>
</li>
<li>Configure your Pi.<ul>
<li><code>sudo raspi-config</code></li>
</ul>
</li>
<li><p>Setting WIFI up and reboot wireless.</p>
<ul>
<li><p><code>sudo vi /etc/wpa_supplicant/wpa_supplicant.conf</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">network=&#123;</div><div class="line">    ssid=&quot;ssid&quot;</div><div class="line">    psk=&quot;password&quot;</div><div class="line">    priority=1</div><div class="line">    id_str=&quot;home&quot;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p><code>sudo reboot</code></p>
</li>
</ul>
</li>
<li>Setting static ip.<ul>
<li><code>ifconfig</code></li>
<li><code>sudo nano /etc/dhcpcd.conf</code><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"># Custom static IP address</div><div class="line">interface wlan0</div><div class="line">static ip_address = 192.168.1.121/24</div><div class="line">static routers = 192.168.1.9</div></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ol>
</li>
<li><p>Writing the image to the SD card, see the guide for your system:</p>
<ul>
<li><a href="https://www.raspberrypi.org/documentation/installation/installing-images/linux.md" target="_blank" rel="external">Linux</a></li>
<li><a href="https://www.raspberrypi.org/documentation/installation/installing-images/mac.md" target="_blank" rel="external">Mac OS</a></li>
<li><a href="https://www.raspberrypi.org/documentation/installation/installing-images/windows.md" target="_blank" rel="external">Windows</a></li>
</ul>
</li>
</ol>
<a id="more"></a>
<ul>
<li><a href="https://www.raspberrypi.org/documentation/installation/installing-images/README.md" target="_blank" rel="external">Installation Guide</a></li>
<li><a href="https://hackernoon.com/raspberry-pi-headless-install-462ccabd75d0" target="_blank" rel="external">Headless Raspberry Pi Setup</a></li>
<li><a href="http://www.jianshu.com/p/5dc83db2b78e" target="_blank" rel="external">Mac下安装树莓派系统raspbian</a></li>
</ul>
<h2 id="Prepare"><a href="#Prepare" class="headerlink" title="Prepare"></a>Prepare</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo apt-get update</div></pre></td></tr></table></figure>
<h3 id="Vim"><a href="#Vim" class="headerlink" title="Vim"></a>Vim</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"># vim</div><div class="line">sudo apt-get remove vim-common</div><div class="line">sudo apt-get install vim</div><div class="line"></div><div class="line"># config vim</div><div class="line">sudo vi /etc/vim/vimrc</div><div class="line"></div><div class="line"># 显示行号</div><div class="line">set nu</div><div class="line"># tab 退四格</div><div class="line">set tabstop=4</div><div class="line"># 语法高亮</div><div class="line">syntax on</div><div class="line"># 显示空白符</div><div class="line"># http://stackoverflow.com/questions/1675688/make-vim-show-all-white-spaces-as-a-character</div><div class="line"></div><div class="line"># howto: http://vimsheet.com/</div></pre></td></tr></table></figure>
<h3 id="Samba"><a href="#Samba" class="headerlink" title="Samba"></a>Samba</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"># samba</div><div class="line">sudo apt-get install samba samba-common-bin</div><div class="line"></div><div class="line"># config samba</div><div class="line">sudo vi /etc/samba/smb.conf</div><div class="line"></div><div class="line">[homes]</div><div class="line">  read only = no</div><div class="line"></div><div class="line"># restart</div><div class="line">sudo /etc/init.d/samba restart</div><div class="line"># add user</div><div class="line">sudo smbpasswd -a pi</div><div class="line"></div><div class="line"># Connect it under &quot;Shared of Finder on Mac&quot;</div></pre></td></tr></table></figure>
<h3 id="Python"><a href="#Python" class="headerlink" title="Python"></a>Python</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">python --version</div><div class="line"></div><div class="line"># pip</div><div class="line">which pip</div><div class="line">curl -O https://bootstrap.pypa.io/get-pip.py</div><div class="line">sudo python get-pip.py</div><div class="line"></div><div class="line"># config pip</div><div class="line">vi ~/.pip/pip.conf</div><div class="line"></div><div class="line">[global]</div><div class="line">format=columns</div><div class="line">index-url = https://mirrors.aliyun.com/pypi/simple/</div><div class="line">trusted-host = mirrors.aliyun.com</div><div class="line"></div><div class="line">pip list [--outdated]</div><div class="line">sudo pip install --upgrade (package)</div><div class="line"></div><div class="line"># GPIO</div><div class="line">sudo pip install RPi.GPIO</div></pre></td></tr></table></figure>
<h3 id="Then"><a href="#Then" class="headerlink" title="Then"></a>Then</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo apt-get remove</div></pre></td></tr></table></figure>
<h2 id="Usage"><a href="#Usage" class="headerlink" title="Usage"></a>Usage</h2><p>Light a LED and so on.</p>
<p>RPi.GPIO: <a href="https://sourceforge.net/p/raspberry-gpio-python/wiki/Home/" target="_blank" rel="external">https://sourceforge.net/p/raspberry-gpio-python/wiki/Home/</a></p>
<p><code>vi led.py</code>:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">#!/usr/bin/env python</div><div class="line"># -*- coding:utf-8 -*-</div><div class="line">import RPi.GPIO as GPIO</div><div class="line">import time</div><div class="line"></div><div class="line">print(GPIO.RPI_INFO)</div><div class="line"></div><div class="line">LED = 26</div><div class="line"></div><div class="line">GPIO.setmode(GPIO.BCM)</div><div class="line">GPIO.setup(LED, GPIO.OUT)</div><div class="line">try:</div><div class="line">    while True:</div><div class="line">        GPIO.output(LED, GPIO.HIGH)</div><div class="line">        time.sleep(1)</div><div class="line">        GPIO.output(LED, GPIO.LOW)</div><div class="line">        time.sleep(1)</div><div class="line">except:</div><div class="line">    print(&quot;except&quot;)</div><div class="line">GPIO.cleanup()</div></pre></td></tr></table></figure>
<p><code>vi key.py</code>:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">#!/usr/bin/env python</div><div class="line"># -*- coding:utf-8 -*-</div><div class="line">import RPi.GPIO as GPIO</div><div class="line">import time</div><div class="line"></div><div class="line">KEY = 20</div><div class="line"></div><div class="line">GPIO.setmode(GPIO.BCM)</div><div class="line">GPIO.setup(KEY, GPIO.IN, GPIO.PUD_UP)</div><div class="line">while True:</div><div class="line">    time.sleep(0.05)</div><div class="line">    if GPIO.input(KEY) == 0:</div><div class="line">        print(&quot;KEY PRESS&quot;)</div><div class="line">        while GPIO.input(KEY) == 0:</div><div class="line">            time.sleep(0.01)</div></pre></td></tr></table></figure>
<p><code>vi event.py</code>:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">#!/usr/bin/env python</div><div class="line"># -*- coding:utf-8 -*-</div><div class="line">import RPi.GPIO as GPIO</div><div class="line">import time</div><div class="line"></div><div class="line">KEY = 20</div><div class="line"></div><div class="line">def MyInterrupt(KEY):</div><div class="line">    print(&quot;KEY PRESS&quot;)</div><div class="line"></div><div class="line">GPIO.setmode(GPIO.BCM)</div><div class="line">GPIO.setup(KEY, GPIO.IN, GPIO.PUD_UP)</div><div class="line">GPIO.add_event_detect(KEY, GPIO.FALLING, MyInterrupt, 200)</div><div class="line"></div><div class="line">while True:</div><div class="line">    time.sleep(1)</div></pre></td></tr></table></figure>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Install&quot;&gt;&lt;a href=&quot;#Install&quot; class=&quot;headerlink&quot; title=&quot;Install&quot;&gt;&lt;/a&gt;Install&lt;/h2&gt;
&lt;style type=&quot;text/css&quot;&gt;
.post-body li p { margin: 0; }
&lt;/style&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.raspberrypi.org/downloads/raspbian/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Download&lt;/a&gt; “RASPBIAN JESSIE LITE” without PIXEL desktop.&lt;/li&gt;
&lt;li&gt;Unzip it to get the image file (.img) for writing to your SD card.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup headless settings, &lt;strong&gt;if don’t have an extra keyboard or HDMI cable&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add “ssh” file to the SD card root. Then boot your Pi.&lt;/li&gt;
&lt;li&gt;Connect it to the router with wire. Then get its ip from the router.&lt;/li&gt;
&lt;li&gt;Use SSH to connect to your Pi.&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh pi@&amp;lt;IP&amp;gt;&lt;/code&gt;, password: raspberry.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Configure your Pi.&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo raspi-config&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setting WIFI up and reboot wireless.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo vi /etc/wpa_supplicant/wpa_supplicant.conf&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;network=&amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    ssid=&amp;quot;ssid&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    psk=&amp;quot;password&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    priority=1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    id_str=&amp;quot;home&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&amp;#125;&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo reboot&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Setting static ip.&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ifconfig&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo nano /etc/dhcpcd.conf&lt;/code&gt;&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;# Custom static IP address&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;interface wlan0&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;static ip_address = 192.168.1.121/24&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;static routers = 192.168.1.9&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing the image to the SD card, see the guide for your system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.raspberrypi.org/documentation/installation/installing-images/linux.md&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.raspberrypi.org/documentation/installation/installing-images/mac.md&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Mac OS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.raspberrypi.org/documentation/installation/installing-images/windows.md&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Windows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="Raspberry Pi" scheme="http://eevee.cc/tags/Raspberry-Pi/"/>
    
      <category term="SSH" scheme="http://eevee.cc/tags/SSH/"/>
    
  </entry>
  
  <entry>
    <title>Build OpenCV for Android with CUDA</title>
    <link href="http://eevee.cc/2017/05/05/build-ocv-for-android-with-cuda/"/>
    <id>http://eevee.cc/2017/05/05/build-ocv-for-android-with-cuda/</id>
    <published>2017-05-05T07:31:13.000Z</published>
    <updated>2017-05-09T02:04:20.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Prerequisites"><a href="#Prerequisites" class="headerlink" title="Prerequisites"></a>Prerequisites</h2><ul>
<li>Ubuntu 14.04 LTS<ul>
<li><a href="https://wiki.ubuntu.com/TrustyTahr/ReleaseNotes" target="_blank" rel="external">Download here</a></li>
</ul>
</li>
<li>NVIDIA CodeWorks for Android 1R4<ul>
<li><a href="https://docs.nvidia.com/gameworks/index.html#developertools/mobile/codeworks_android/codeworks_android_1r4.htm" target="_blank" rel="external">Doc here</a></li>
<li><a href="https://developer.nvidia.com/codeworks-android-archive" target="_blank" rel="external">Download here</a></li>
<li>Could only select actions: CUDA ToolKit 7.0, CUDA for Android 7.0</li>
</ul>
</li>
<li><a href="https://developer.android.com/studio/index.html" target="_blank" rel="external">Android Studio</a><ul>
<li><a href="https://developer.android.com/studio/projects/add-native-code.html" target="_blank" rel="external">Add C and C++ Code to Your Project</a></li>
</ul>
</li>
</ul>
<h2 id="Prepare"><a href="#Prepare" class="headerlink" title="Prepare"></a>Prepare</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"># Set environment variables</div><div class="line">$ vi ~/.bashrc</div><div class="line"># Android SDK &amp; NDK</div><div class="line">export ANDROID_SDK=$HOME/Android/Sdk</div><div class="line">export ANDROID_NDK=$ANDROID_SDK/ndk-bundle</div><div class="line">export ANDROID_STANDALONE_TOOLCHAIN=$ANDROID_NDK/toolchains</div><div class="line">export PATH=$PATH:$ANDROID_SDK/tools:$ANDROID_SDK/tools/bin:$ANDROID_SDK/platform-tools:$ANDROID_NDK</div><div class="line"># Java SDK 1.8 (could ignore, for latest android command-line tool)</div><div class="line">export JAVA_HOME=$HOME/Develop/jdk1.8.0_131</div><div class="line">export PATH=$JAVA_HOME/bin:$PATH</div><div class="line">$ source ~/.bashrc</div><div class="line"></div><div class="line"># Enable OpenCV Java wrappers</div><div class="line">$ sudo apt-get install ant</div><div class="line"></div><div class="line"># Downgrade android command-line tool</div><div class="line">$ cd $ANDROID_SDK</div><div class="line">$ mv tools/ tools-backup/</div><div class="line">$ curl -O https://dl.google.com/android/repository/tools_r25.2.3-linux.zip</div><div class="line">$ unzip -q tools_r25.2.3-linux.zip</div></pre></td></tr></table></figure>
<h2 id="Build"><a href="#Build" class="headerlink" title="Build"></a>Build</h2><a id="more"></a>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">$ cd opencv-3.2.0/platforms/</div><div class="line">$ mkdir -p build_android_arm</div><div class="line">$ cd build_android_arm/</div><div class="line">$ cmake -DCMAKE_BUILD_TYPE=RELEASE \</div><div class="line">-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \</div><div class="line">-DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake \</div><div class="line">\</div><div class="line">-DCUDA_TOOLKIT_ROOT_DIR=$HOME/NVPACK/cuda-7.0 \</div><div class="line">-DCUDA_ARCH_BIN=&quot;5.3&quot; \</div><div class="line">-DCUDA_ARCH_PTX=&quot;&quot; \</div><div class="line">-DCUDA_FAST_MATH=ON \</div><div class="line">-DWITH_CUDA=ON \</div><div class="line">-DWITH_CUFFT=OFF \</div><div class="line">-DWITH_CUBLAS=OFF \</div><div class="line">-DWITH_OPENCL=OFF \</div><div class="line">\</div><div class="line">-DBUILD_SHARED_LIBS=OFF \</div><div class="line">-DBUILD_DOCS=OFF \</div><div class="line">-DBUILD_EXAMPLES=OFF \</div><div class="line">-DBUILD_TESTS=OFF \</div><div class="line">-DBUILD_PERF_TESTS=OFF \</div><div class="line">../..</div></pre></td></tr></table></figure>
<p>Result:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div></pre></td><td class="code"><pre><div class="line">-- General configuration for OpenCV 3.2.0 =====================================</div><div class="line">--   Version control:               unknown</div><div class="line">--</div><div class="line">--   Platform:</div><div class="line">--     Timestamp:                   2017-05-05T05:05:05Z</div><div class="line">--     Host:                        Linux 4.4.0-75-generic x86_64</div><div class="line">--     Target:                      Linux 1 armv7-a</div><div class="line">--     CMake:                       2.8.12.2</div><div class="line">--     CMake generator:             Unix Makefiles</div><div class="line">--     CMake build tool:            /usr/bin/make</div><div class="line">--     Configuration:               RELEASE</div><div class="line">--</div><div class="line">--   C/C++:</div><div class="line">--     Built as dynamic libs?:      NO</div><div class="line">--     C++ Compiler:                /home/john/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++  (ver 4.9)</div><div class="line">--     C++ flags (Release):         -fexceptions -frtti -fpic -Wno-psabi --sysroot=/home/john/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm -funwind-tables -finline-limit=64 -fsigned-char -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fdata-sections -ffunction-sections -Wa,--noexecstack    -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -fomit-frame-pointer -mfp16-format=ieee -fvisibility=hidden -fvisibility-inlines-hidden -mthumb -fomit-frame-pointer -fno-strict-aliasing -O3 -DNDEBUG  -DNDEBUG</div><div class="line">--     C++ flags (Debug):           -fexceptions -frtti -fpic -Wno-psabi --sysroot=/home/john/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm -funwind-tables -finline-limit=64 -fsigned-char -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fdata-sections -ffunction-sections -Wa,--noexecstack    -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -fomit-frame-pointer -mfp16-format=ieee -fvisibility=hidden -fvisibility-inlines-hidden -marm -fno-omit-frame-pointer -fno-strict-aliasing -O0 -g -DDEBUG -D_DEBUG  -O0 -DDEBUG -D_DEBUG</div><div class="line">--     C Compiler:                  /home/john/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc</div><div class="line">--     C flags (Release):           -fexceptions -fpic -Wno-psabi --sysroot=/home/john/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm -funwind-tables -finline-limit=64 -fsigned-char -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fdata-sections -ffunction-sections -Wa,--noexecstack    -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -fomit-frame-pointer -mfp16-format=ieee -fvisibility=hidden -mthumb -fomit-frame-pointer -fno-strict-aliasing -O3 -DNDEBUG  -DNDEBUG</div><div class="line">--     C flags (Debug):             -fexceptions -fpic -Wno-psabi --sysroot=/home/john/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm -funwind-tables -finline-limit=64 -fsigned-char -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fdata-sections -ffunction-sections -Wa,--noexecstack    -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -fomit-frame-pointer -mfp16-format=ieee -fvisibility=hidden -marm -fno-omit-frame-pointer -fno-strict-aliasing -O0 -g -DDEBUG -D_DEBUG  -O0 -DDEBUG -D_DEBUG</div><div class="line">--     Linker flags (Release):      -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-allow-shlib-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now</div><div class="line">--     Linker flags (Debug):        -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-allow-shlib-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now</div><div class="line">--     ccache:                      YES</div><div class="line">--     Precompiled headers:         NO</div><div class="line">--     Extra dependencies:          z dl m log cudart nppc nppi npps -L/home/john/NVPACK/cuda-7.0/targets/armv7-linux-androideabi/lib -L/home/john/NVPACK/cuda-7.0/targets/armv7-linux-androideabi/lib/stubs</div><div class="line">--     3rdparty dependencies:       libjpeg libwebp libpng libtiff libjasper IlmImf tegra_hal</div><div class="line">--</div><div class="line">--   OpenCV modules:</div><div class="line">--     To be built:                 cudev core cudaarithm flann imgproc ml video cudabgsegm cudafilters cudaimgproc cudawarping imgcodecs photo shape videoio cudacodec highgui objdetect features2d calib3d cudafeatures2d cudalegacy cudaobjdetect cudaoptflow cudastereo java stitching superres videostab</div><div class="line">--     Disabled:                    world</div><div class="line">--     Disabled by dependency:      -</div><div class="line">--     Unavailable:                 python2 ts viz</div><div class="line">--</div><div class="line">--   Android:</div><div class="line">--     Android ABI:                 armeabi-v7a</div><div class="line">--     STL type:                    gnustl_static</div><div class="line">--     Native API level:            android-9</div><div class="line">--     SDK target:                  android-21</div><div class="line">--     Android NDK:                 /home/john/Android/Sdk/ndk-bundle (toolchain: arm-linux-androideabi-4.9)</div><div class="line">--     android tool:                /home/john/Android/Sdk/tools/android (Android SDK Tools, revision 25.2.3.)</div><div class="line">--     Google Play manager:         NO</div><div class="line">--     Android examples:            YES</div><div class="line">--</div><div class="line">--   GUI:</div><div class="line">--     GTK+:                        NO</div><div class="line">--     GThread :                    NO</div><div class="line">--     GtkGlExt:                    NO</div><div class="line">--     OpenGL support:              NO</div><div class="line">--     VTK support:                 NO</div><div class="line">--</div><div class="line">--   Media I/O:</div><div class="line">--     ZLib:                        z (ver 1.2.3)</div><div class="line">--     JPEG:                        build (ver 90)</div><div class="line">--     WEBP:                        build (ver 0.3.1)</div><div class="line">--     PNG:                         build (ver 1.6.24)</div><div class="line">--     TIFF:                        build (ver 42 - 4.0.2)</div><div class="line">--     JPEG 2000:                   build (ver 1.900.1)</div><div class="line">--     OpenEXR:                     build (ver 1.7.1)</div><div class="line">--     GDAL:                        NO</div><div class="line">--     GDCM:                        NO</div><div class="line">--</div><div class="line">--   Video I/O:</div><div class="line">--</div><div class="line">--   Parallel framework:            pthreads</div><div class="line">--</div><div class="line">--   Other third-party libraries:</div><div class="line">--     Use IPP:                     NO</div><div class="line">--     Use Eigen:                   YES (ver 3.2.0)</div><div class="line">--     Use Cuda:                    YES (ver 7.0)</div><div class="line">--     Use OpenCL:                  NO</div><div class="line">--     Use OpenVX:                  NO</div><div class="line">--     Use custom HAL:              YES (carotene (ver 0.0.1))</div><div class="line">--</div><div class="line">--   NVIDIA CUDA</div><div class="line">--     Use CUFFT:                   NO</div><div class="line">--     Use CUBLAS:                  NO</div><div class="line">--     USE NVCUVID:                 NO</div><div class="line">--     NVIDIA GPU arch:             53</div><div class="line">--     NVIDIA PTX archs:</div><div class="line">--     Use fast math:               YES</div><div class="line">--</div><div class="line">--   Python 2:</div><div class="line">--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.6)</div><div class="line">--</div><div class="line">--   Python 3:</div><div class="line">--     Interpreter:                 /usr/bin/python3.4 (ver 3.4.3)</div><div class="line">--</div><div class="line">--   Python (for build):            /usr/bin/python2.7</div><div class="line">--</div><div class="line">--   Java:</div><div class="line">--     ant:                         /usr/bin/ant (ver 1.9.3)</div><div class="line">--     Java wrappers:               YES</div><div class="line">--     Java tests:                  NO</div><div class="line">--</div><div class="line">--   Matlab:                        NO</div><div class="line">--</div><div class="line">--   Tests and samples:</div><div class="line">--     Tests:                       NO</div><div class="line">--     Performance tests:           NO</div><div class="line">--     C/C++ Examples:              NO</div><div class="line">--</div><div class="line">--   Install path:                  /home/john/Workspace/opencv-3.2.0/platforms/build_android_arm/install</div><div class="line">--</div><div class="line">--   cvconfig.h is in:              /home/john/Workspace/opencv-3.2.0/platforms/build_android_arm</div><div class="line">-- -----------------------------------------------------------------</div></pre></td></tr></table></figure>
<p>Make:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ make -j8</div><div class="line"># Or,</div><div class="line">$ make -j$(python -c &apos;import multiprocessing as mp; print(mp.cpu_count())&apos;)</div></pre></td></tr></table></figure>
<p>Alternatives (ignored):</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">$ cd opencv-3.2.0/platforms/</div><div class="line">$ ./scripts/cmake_android_arm.sh</div><div class="line"></div><div class="line"># Tegra X1: https://developer.nvidia.com/content/tegra-x1</div><div class="line">-D CUDA_GENERATION=Maxwell</div></pre></td></tr></table></figure>
<h2 id="Usage"><a href="#Usage" class="headerlink" title="Usage"></a>Usage</h2><p>Open “Android Studio” and,</p>
<ul>
<li>“Import Module” from “build_android_arm” directory.<ul>
<li>Exclude “jni”, only keep “aidl”, “java”, “res/values/attrs.xml”</li>
</ul>
</li>
</ul>
<p>Ensure it’s the same file structure as the offical <a href="http://opencv.org/platforms/android/" target="_blank" rel="external">OpenCV4Android</a>.</p>
<p>About the sample project, you could find <a href="https://github.com/joinAero/DroidTurbo/tree/master-cuda" target="_blank" rel="external">here</a>.</p>
<h2 id="Issues"><a href="#Issues" class="headerlink" title="Issues"></a>Issues</h2><h3 id="Issue-when-cmake"><a href="#Issue-when-cmake" class="headerlink" title="Issue when cmake"></a>Issue when <code>cmake</code></h3><pre><code>Failed to get list of installed Android targets.

CMake Warning at cmake/OpenCVDetectAndroidSDK.cmake:205 (message):
  Can not find any SDK target compatible with: 9 11
</code></pre><p>And,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">$ android list target -c</div><div class="line">*************************************************************************</div><div class="line">The &quot;android&quot; command is deprecated.</div><div class="line">For manual SDK, AVD, and project management, please use Android Studio.</div><div class="line">For command-line tools, use tools/bin/sdkmanager and tools/bin/avdmanager</div><div class="line">*************************************************************************</div><div class="line">Running /home/john/Android/Sdk/tools/bin/avdmanager list target -c</div><div class="line"></div><div class="line">Exception in thread &quot;main&quot; java.lang.UnsupportedClassVersionError: com/android/sdklib/tool/AvdManagerCli : Unsupported major.minor version 52.0</div><div class="line">    at java.lang.ClassLoader.defineClass1(Native Method)</div><div class="line">    at java.lang.ClassLoader.defineClass(ClassLoader.java:803)</div><div class="line">    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)</div><div class="line">    at java.net.URLClassLoader.defineClass(URLClassLoader.java:442)</div><div class="line">    at java.net.URLClassLoader.access$100(URLClassLoader.java:64)</div><div class="line">    at java.net.URLClassLoader$1.run(URLClassLoader.java:354)</div><div class="line">    at java.net.URLClassLoader$1.run(URLClassLoader.java:348)</div><div class="line">    at java.security.AccessController.doPrivileged(Native Method)</div><div class="line">    at java.net.URLClassLoader.findClass(URLClassLoader.java:347)</div><div class="line">    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)</div><div class="line">    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)</div><div class="line">    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)</div><div class="line">    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)</div></pre></td></tr></table></figure>
<p>Solution:</p>
<ul>
<li>Install Java SDK 1.8<ul>
<li>Fix “UnsupportedClassVersionError …”</li>
</ul>
</li>
<li><p>Amend match of android sdk targets</p>
  <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ cd opencv-3.2.0/</div><div class="line">$ vi cmake/OpenCVDetectAndroidSDK.cmake</div><div class="line"># line 98, change &quot;[^\n]+&quot; to &quot;android-[0-9]+&quot;</div><div class="line">string(REGEX MATCHALL &quot;android-[0-9]+&quot; ANDROID_SDK_TARGETS &quot;$&#123;ANDROID_SDK_TARGETS&#125;&quot;)</div></pre></td></tr></table></figure>
<ul>
<li>Or, <code>cmake</code> with <code>-DANDROID_EXECUTABLE=$ANDROID_SDK/tools/bin/avdmanager</code></li>
<li>WARN： However, <code>make</code> still will fail in “Generating OpenCV Android library project.”</li>
</ul>
</li>
</ul>
<h3 id="Issue-when-make"><a href="#Issue-when-make" class="headerlink" title="Issue when make"></a>Issue when <code>make</code></h3><pre><code>[ 92%] Generating OpenCV Android library project. SDK target: android-21
*************************************************************************
The &quot;android&quot; command is deprecated.
For manual SDK, AVD, and project management, please use Android Studio.
For command-line tools, use tools/bin/sdkmanager and tools/bin/avdmanager
*************************************************************************
Invalid or unsupported command &quot;--silent create lib-project --path /home/john/Workspace/opencv-3.2.0/platforms/build_android_arm --target android-21 --name OpenCV --package org.opencv&quot;

Supported commands are:
android list target
android list avd
android list device
android create avd
android move avd
android delete avd
android list sdk
android update sdk
make[2]: *** [build.xml] Error 2
make[1]: *** [modules/java/CMakeFiles/opencv_java.dir/all] Error 2
make: *** [all] Error 2
</code></pre><p>Solution:</p>
<ul>
<li>Downgrade <a href="https://developer.android.com/studio/tools/help/android.html" target="_blank" rel="external">android</a> command-line tool  <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">$ cd $ANDROID_SDK</div><div class="line">$ mv tools/ tools-backup/</div><div class="line"></div><div class="line">$ curl -O https://dl.google.com/android/repository/tools_r25.2.3-linux.zip</div><div class="line">$ unzip -q tools_r25.2.3-linux.zip</div></pre></td></tr></table></figure>
</li>
</ul>
<p>Learn more:</p>
<ul>
<li><a href="https://issuetracker.google.com/issues/37137207" target="_blank" rel="external">Tools 25.3.1 deprecation of ‘android’ command line tool breaks Unity3D build</a></li>
</ul>
<h2 id="References"><a href="#References" class="headerlink" title="References"></a>References</h2><ul>
<li><a href="http://opencv.org/platforms/android/" target="_blank" rel="external">OpenCV Platforms Android</a></li>
<li><a href="http://code.opencv.org/projects/opencv/wiki/Building_OpenCV4Android_from_trunk" target="_blank" rel="external">Building OpenCV4Android from trunk</a></li>
<li><a href="https://zami0xzami.wordpress.com/2016/03/17/building-opencv-for-android-from-source/" target="_blank" rel="external">Building OpenCV &amp; OpenCV Extra Modules For Android From Source</a></li>
<li><a href="http://docs.opencv.org/master/d6/d15/tutorial_building_tegra_cuda.html" target="_blank" rel="external">Building OpenCV for Tegra with CUDA</a></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Prerequisites&quot;&gt;&lt;a href=&quot;#Prerequisites&quot; class=&quot;headerlink&quot; title=&quot;Prerequisites&quot;&gt;&lt;/a&gt;Prerequisites&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Ubuntu 14.04 LTS&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.ubuntu.com/TrustyTahr/ReleaseNotes&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Download here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NVIDIA CodeWorks for Android 1R4&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.nvidia.com/gameworks/index.html#developertools/mobile/codeworks_android/codeworks_android_1r4.htm&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Doc here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.nvidia.com/codeworks-android-archive&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Download here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Could only select actions: CUDA ToolKit 7.0, CUDA for Android 7.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/studio/index.html&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Android Studio&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/studio/projects/add-native-code.html&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Add C and C++ Code to Your Project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;Prepare&quot;&gt;&lt;a href=&quot;#Prepare&quot; class=&quot;headerlink&quot; title=&quot;Prepare&quot;&gt;&lt;/a&gt;Prepare&lt;/h2&gt;&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;7&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;8&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;9&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;10&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;11&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;12&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;13&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;14&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;15&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;16&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;17&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;18&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;19&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;20&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;# Set environment variables&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ vi ~/.bashrc&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# Android SDK &amp;amp; NDK&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;export ANDROID_SDK=$HOME/Android/Sdk&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;export ANDROID_NDK=$ANDROID_SDK/ndk-bundle&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;export ANDROID_STANDALONE_TOOLCHAIN=$ANDROID_NDK/toolchains&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;export PATH=$PATH:$ANDROID_SDK/tools:$ANDROID_SDK/tools/bin:$ANDROID_SDK/platform-tools:$ANDROID_NDK&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# Java SDK 1.8 (could ignore, for latest android command-line tool)&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;export JAVA_HOME=$HOME/Develop/jdk1.8.0_131&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;export PATH=$JAVA_HOME/bin:$PATH&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ source ~/.bashrc&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# Enable OpenCV Java wrappers&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ sudo apt-get install ant&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# Downgrade android command-line tool&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ cd $ANDROID_SDK&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ mv tools/ tools-backup/&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ curl -O https://dl.google.com/android/repository/tools_r25.2.3-linux.zip&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ unzip -q tools_r25.2.3-linux.zip&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;Build&quot;&gt;&lt;a href=&quot;#Build&quot; class=&quot;headerlink&quot; title=&quot;Build&quot;&gt;&lt;/a&gt;Build&lt;/h2&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="Android" scheme="http://eevee.cc/tags/Android/"/>
    
      <category term="CUDA" scheme="http://eevee.cc/tags/CUDA/"/>
    
      <category term="OpenCV" scheme="http://eevee.cc/tags/OpenCV/"/>
    
  </entry>
  
  <entry>
    <title>Use ccache, distcc, dmucs to accelerate builds</title>
    <link href="http://eevee.cc/2017/05/05/use-ccache-distcc-dmucs-to-accelerate-builds/"/>
    <id>http://eevee.cc/2017/05/05/use-ccache-distcc-dmucs-to-accelerate-builds/</id>
    <published>2017-05-05T03:29:26.000Z</published>
    <updated>2017-05-09T02:04:41.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="ccache"><a href="#ccache" class="headerlink" title="ccache"></a><a href="http://ccache.samba.org/" target="_blank" rel="external">ccache</a></h2><p><a href="http://ccache.samba.org/" target="_blank" rel="external">ccache</a> is a compiler cache. It speeds up recompilation by caching previous compilations and detecting when the same compilation is being done again. Supported languages are C, C++, Objective-C and Objective-C++.</p>
<p>Mac:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"># install</div><div class="line">$ brew install ccache</div><div class="line"></div><div class="line"># where</div><div class="line">$ brew ls ccache</div><div class="line">$ which ccache</div><div class="line"></div><div class="line">$ brew info ccache</div><div class="line"></div><div class="line"># env</div><div class="line">$ vi ~/.bash_profile</div><div class="line"></div><div class="line">    export PATH=/usr/local/opt/ccache/libexec:$PATH</div><div class="line"></div><div class="line"># verify</div><div class="line">$ source ~/.bash_profile</div><div class="line">$ which clang</div><div class="line">/usr/local/opt/ccache/libexec/clang</div></pre></td></tr></table></figure>
<p>Ubuntu:</p>
<a id="more"></a>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"># install</div><div class="line">$ sudo apt-get install ccache</div><div class="line"></div><div class="line"># where</div><div class="line">$ whereis ccache</div><div class="line">$ which ccache</div><div class="line"></div><div class="line"># env</div><div class="line">$ vi ~/.bashrc</div><div class="line"></div><div class="line">    export PATH=/usr/lib/ccache:$PATH</div><div class="line"></div><div class="line"># verify</div><div class="line">$ source ~/.bashrc</div><div class="line">$ which g++ gcc</div><div class="line">/usr/lib/ccache/g++</div><div class="line">/usr/lib/ccache/gcc</div></pre></td></tr></table></figure>
<ul>
<li><a href="https://chromium.googlesource.com/chromium/src/+/master/docs/ccache_mac.md" target="_blank" rel="external">Using CCache on Mac</a></li>
</ul>
<h2 id="distcc-on-Ubuntu"><a href="#distcc-on-Ubuntu" class="headerlink" title="distcc on Ubuntu"></a><a href="https://github.com/distcc/distcc" target="_blank" rel="external">distcc</a> on Ubuntu</h2><p><a href="https://github.com/distcc/distcc" target="_blank" rel="external">distcc</a> is a program to distribute compilation of C or C++ code across several machines on a network. <a href="https://github.com/distcc/distcc" target="_blank" rel="external">distcc</a> should always generate the same results as a local compile, is simple to install and use, and is often two or more times faster than a local compile.</p>
<p>Install:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"># install</div><div class="line">$ sudo apt-get install distcc</div><div class="line"># optional</div><div class="line">$ sudo apt-get install distccmon-gnome</div><div class="line"></div><div class="line">$ distcc --help</div><div class="line"></div><div class="line"># show ip</div><div class="line">$ ifconfig | grep &quot;inet &quot; | grep -v 127.0.0.1</div><div class="line">192.168.199.247</div><div class="line"></div><div class="line"># config</div><div class="line">$ sudo vi /etc/default/distcc</div><div class="line"></div><div class="line">    STARTDISTCC=&quot;true&quot;</div><div class="line">    ALLOWEDNETS=&quot;192.168.0.0/16&quot;</div><div class="line">    LISTENER=&quot;&quot;</div><div class="line">    ZEROCONF=&quot;false&quot;</div><div class="line"></div><div class="line"># start server</div><div class="line">$ sudo /etc/init.d/distcc start</div><div class="line"></div><div class="line"># reboot &amp; verify</div><div class="line">$ ps aux | grep distccd</div></pre></td></tr></table></figure>
<p>Usage:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"># download</div><div class="line">$ curl -R -O http://www.lua.org/ftp/lua-5.3.4.tar.gz</div><div class="line">$ tar zxf lua-5.3.4.tar.gz</div><div class="line"></div><div class="line">$ cd lua-5.3.4</div><div class="line"></div><div class="line"># build</div><div class="line">$ time make linux</div><div class="line"></div><div class="line"># clean</div><div class="line">$ make clean; ccache -C</div><div class="line"></div><div class="line"># display distcc jobs, plz in another terminal</div><div class="line">$ distccmon-text 2</div><div class="line"># or, with gui</div><div class="line">$ distccmon-gnome &amp;</div><div class="line"></div><div class="line"># build with distcc</div><div class="line">$ export DISTCC_HOSTS=&quot;192.168.199.247 192.168.199.104&quot;</div><div class="line">$ time make -j12 CC=&quot;distcc gcc -std=gnu99&quot; linux</div></pre></td></tr></table></figure>
<p>Cost:</p>
<table>
<thead>
<tr>
<th></th>
<th style="text-align:right">normal</th>
<th style="text-align:right">ccache</th>
<th style="text-align:right">distcc</th>
<th style="text-align:right">distcc + ccache</th>
</tr>
</thead>
<tbody>
<tr>
<td>cost</td>
<td style="text-align:right">4.069s</td>
<td style="text-align:right">0.134s</td>
<td style="text-align:right">1.301s</td>
<td style="text-align:right">1.296s</td>
</tr>
</tbody>
</table>
<blockquote>
<p>P.S. distcc: 2 quad-core pc, -j12</p>
</blockquote>
<table>
<thead>
<tr>
<th>normal</th>
<th style="text-align:right">make</th>
<th style="text-align:right">make -j4</th>
</tr>
</thead>
<tbody>
<tr>
<td>cost</td>
<td style="text-align:right">4.069s</td>
<td style="text-align:right">1.403s</td>
</tr>
</tbody>
</table>
<p>Use with <a href="http://ccache.samba.org/" target="_blank" rel="external">ccache</a>:</p>
<blockquote>
<p>NOTE: This use of ccache is incompatible with use of distcc’s “pump” mode.</p>
</blockquote>
<h2 id="distcc-on-Mac"><a href="#distcc-on-Mac" class="headerlink" title="distcc on Mac"></a><a href="https://github.com/distcc/distcc" target="_blank" rel="external">distcc</a> on Mac</h2><p>Install:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div></pre></td><td class="code"><pre><div class="line"># install</div><div class="line">$ brew install distcc</div><div class="line"></div><div class="line">$ brew info distcc</div><div class="line">$ distcc --help</div><div class="line">$ distccd --help</div><div class="line"></div><div class="line"># show ip</div><div class="line">$ ifconfig | grep &quot;inet &quot; | grep -v 127.0.0.1</div><div class="line">192.168.199.182</div><div class="line"></div><div class="line"># config</div><div class="line">$ vi /usr/local/Cellar/distcc/3.2rc1/homebrew.mxcl.distcc.plist</div><div class="line"></div><div class="line">    ...</div><div class="line">    &lt;key&gt;ProgramArguments&lt;/key&gt;</div><div class="line">    &lt;array&gt;</div><div class="line">        &lt;string&gt;/usr/local/opt/distcc/bin/distccd&lt;/string&gt;</div><div class="line">        &lt;string&gt;--daemon&lt;/string&gt;</div><div class="line">        &lt;string&gt;--no-detach&lt;/string&gt;</div><div class="line">        &lt;string&gt;--allow=192.168.0.0/16&lt;/string&gt;</div><div class="line">    &lt;/array&gt;</div><div class="line">    ...</div><div class="line"></div><div class="line"># start server</div><div class="line">$ brew services start distcc</div><div class="line"></div><div class="line"># reboot &amp; verify</div><div class="line">$ ps aux | grep distccd</div></pre></td></tr></table></figure>
<p>Usage:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"># download</div><div class="line">$ curl -R -O http://www.lua.org/ftp/lua-5.3.4.tar.gz</div><div class="line">$ tar zxf lua-5.3.4.tar.gz</div><div class="line"></div><div class="line">$ cd lua-5.3.4</div><div class="line"></div><div class="line"># build</div><div class="line">$ time make macosx</div><div class="line"></div><div class="line"># clean</div><div class="line">$ make clean; ccache -C</div><div class="line"></div><div class="line"># display distcc jobs, plz in another terminal</div><div class="line">$ distccmon-text 2</div><div class="line"></div><div class="line"># build with distcc</div><div class="line">$ export DISTCC_HOSTS=&quot;192.168.199.182 192.168.199.105&quot;</div><div class="line">$ vi src/Makefile</div><div class="line"></div><div class="line">    macosx:</div><div class="line">            $(MAKE) $(ALL) SYSCFLAGS=&quot;-DLUA_USE_MACOSX&quot; SYSLIBS=&quot;-lreadline&quot; CC=&quot;distcc cc&quot;</div><div class="line"></div><div class="line">$ time make -j12 macosx</div></pre></td></tr></table></figure>
<blockquote>
<p>Note: It is recommended that using distcc splits different platforms.</p>
</blockquote>
<h2 id="dmucs-on-Ubuntu"><a href="#dmucs-on-Ubuntu" class="headerlink" title="dmucs on Ubuntu"></a><a href="http://dmucs.sourceforge.net/" target="_blank" rel="external">dmucs</a> on Ubuntu</h2><p><a href="http://dmucs.sourceforge.net/" target="_blank" rel="external">DMUCS</a> is a system that allows a group of users to share a compilation farm.  Each compilation request from each user will be sent to the fastest available machine, every time.</p>
<p>Install:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"># install</div><div class="line">$ sudo apt-get install dmucs</div><div class="line"></div><div class="line"># bug fix for restart on boot</div><div class="line">#   dmucs: race condition in start scripts prevents loadavg starting</div><div class="line">#   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=798830</div><div class="line">$ sudo vi /etc/init.d/dmucs</div><div class="line"></div><div class="line">    start)</div><div class="line">          if [ &quot;$SERVER&quot; = &quot;yes&quot; ]; then</div><div class="line">              ...</div><div class="line">              if start_server ;  then</div><div class="line">              ...</div><div class="line">          if [ &quot;$USE_SERVER&quot; ]; then</div><div class="line">              ...</div><div class="line">              if start_loadavg ;  then</div><div class="line">              ...</div></pre></td></tr></table></figure>
<blockquote>
<p>P.S. Unfortunately, this fix doesn’t work on my Ubuntu, although <code>start_loadavg</code> result is ok ==.</p>
<p>You could log the output of “/etc/init.d/dmucs” script, add this at the top:<br>    <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">exec 1&gt;/tmp/init.log 2&gt;&amp;1</div><div class="line">set -x</div></pre></td></tr></table></figure></p>
</blockquote>
<p>Server machine (e.g. 192.168.199.210):</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"># config</div><div class="line">$ sudo vi /etc/default/dmucs</div><div class="line"></div><div class="line">    SERVER=yes</div><div class="line">    USE_SERVER=</div><div class="line"></div><div class="line"># hosts-info</div><div class="line">$ sudo vi /etc/dmucs.conf</div><div class="line"></div><div class="line">    # Format: machine number-of-cpus power-index</div><div class="line">    192.168.199.104   4   8</div><div class="line">    192.168.199.247   4  10</div><div class="line"></div><div class="line"># start</div><div class="line">$ sudo /etc/init.d/dmucs start</div><div class="line"></div><div class="line"># verify restart on boot</div><div class="line">$ sudo reboot</div><div class="line">$ ps aux | grep dmucs</div><div class="line"></div><div class="line"># display which hosts/cpus are available</div><div class="line">$ monitor</div></pre></td></tr></table></figure>
<p>Each host (e.g. 192.168.199.104 192.168.199.247):</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"># config</div><div class="line">$ sudo vi /etc/default/dmucs</div><div class="line"></div><div class="line">    SERVER=no</div><div class="line">    USE_SERVER=192.168.199.210</div><div class="line"></div><div class="line"># start</div><div class="line">$ sudo /etc/init.d/dmucs start</div><div class="line"></div><div class="line"># verify restart on boot</div><div class="line">$ sudo reboot</div><div class="line">$ ps aux | grep loadavg</div></pre></td></tr></table></figure>
<p>Usage:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ cd lua-5.3.4</div><div class="line"></div><div class="line"># build</div><div class="line">$ time make -j12 CC=&quot;gethost -s 192.168.199.210 distcc gcc -std=gnu99&quot; linux</div></pre></td></tr></table></figure>
<h3 id="Issue-loadavg-get-wrong-host-on-Ubuntu-14-04-then-dmucs-not-recognize-the-hosts"><a href="#Issue-loadavg-get-wrong-host-on-Ubuntu-14-04-then-dmucs-not-recognize-the-hosts" class="headerlink" title="Issue: loadavg get wrong host on Ubuntu 14.04, then dmucs not recognize the hosts"></a>Issue: <code>loadavg</code> get wrong host on Ubuntu 14.04, then <code>dmucs</code> not recognize the hosts</h3><p>Run <code>loadavg -s 192.168.199.210 -D</code>, see “Writing –&gt;127.0.1.1 …&lt;– to the server”.</p>
<p>Easily avoid this issue as follows:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"># comment host &quot;127.0.1.1&quot;</div><div class="line">$ sudo vi /etc/hosts</div><div class="line"></div><div class="line">    127.0.0.1   localhost</div><div class="line">    #127.0.1.1  ubuntu</div><div class="line">    ...</div><div class="line"></div><div class="line"># restart loadavg</div><div class="line">$ sudo /etc/init.d/dmucs restart</div></pre></td></tr></table></figure>
<p>However, it will affect dnsmasq at least.</p>
<p>Learn more, plz google “127.0.1.1”, “ubuntu dnsmasq 127.0.1.1”.</p>
<!--

<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"># enable &quot;/etc/init.d/*&quot; scripts</div><div class="line">sudo update-rc.d &lt;script&gt; defaults</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"># log for &quot;/etc/init.d/*&quot; scripts</div><div class="line">exec 1&gt;/tmp/init.log 2&gt;&amp;1</div><div class="line">set -x</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"># restore configure</div><div class="line"># https://askubuntu.com/questions/66533/how-can-i-restore-configuration-files</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"># download [here](https://sourceforge.net/projects/dmucs/)</div><div class="line">$ tar jxf dmucs-0.6.tar.bz2</div><div class="line"></div><div class="line">$ cd dmucs/</div><div class="line"></div><div class="line"># build</div><div class="line">$ ./configure \</div><div class="line">CPPFLAGS=-DSERVER_MACH_NAME=\\\&quot;192.168.199.210\\\&quot;</div><div class="line">$ make</div><div class="line">$ make install</div></pre></td></tr></table></figure>
<ul>
<li><a href="http://jhshi.me/2013/11/02/how-to-get-hosts-ip-address/">How to Get Local Host’s Real IP Address</a></li>
</ul>
<p>–&gt;</p>
-->]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;ccache&quot;&gt;&lt;a href=&quot;#ccache&quot; class=&quot;headerlink&quot; title=&quot;ccache&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://ccache.samba.org/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;ccache&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;http://ccache.samba.org/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;ccache&lt;/a&gt; is a compiler cache. It speeds up recompilation by caching previous compilations and detecting when the same compilation is being done again. Supported languages are C, C++, Objective-C and Objective-C++.&lt;/p&gt;
&lt;p&gt;Mac:&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;7&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;8&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;9&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;10&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;11&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;12&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;13&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;14&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;15&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;16&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;17&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;18&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;# install&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ brew install ccache&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# where&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ brew ls ccache&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ which ccache&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ brew info ccache&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# env&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ vi ~/.bash_profile&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    export PATH=/usr/local/opt/ccache/libexec:$PATH&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# verify&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ source ~/.bash_profile&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ which clang&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;/usr/local/opt/ccache/libexec/clang&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Ubuntu:&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="ccache" scheme="http://eevee.cc/tags/ccache/"/>
    
      <category term="distcc" scheme="http://eevee.cc/tags/distcc/"/>
    
      <category term="dmucs" scheme="http://eevee.cc/tags/dmucs/"/>
    
  </entry>
  
  <entry>
    <title>Install Caffe &amp; TensorFlow with Python and CUDA (macOS)</title>
    <link href="http://eevee.cc/2017/04/12/install-caffe-tf/"/>
    <id>http://eevee.cc/2017/04/12/install-caffe-tf/</id>
    <published>2017-04-12T09:22:25.000Z</published>
    <updated>2017-05-09T02:04:26.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Requirements"><a href="#Requirements" class="headerlink" title="Requirements"></a>Requirements</h2><h3 id="Python-Installation"><a href="#Python-Installation" class="headerlink" title="Python Installation"></a>Python Installation</h3><p><a href="https://github.com/pyenv/pyenv" target="_blank" rel="external">pyenv</a></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">$ brew install pyenv</div><div class="line">$ pyenv install --list</div><div class="line">$ pyenv install anaconda3-4.3.1</div><div class="line">$ pyenv global anaconda3-4.3.1</div><div class="line">$ pyenv versions</div><div class="line">  system</div><div class="line">* anaconda3-4.3.1 (set by /Users/John/.pyenv/version)</div></pre></td></tr></table></figure>
<p>Enable pyenv in your shell:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ vi ~/.bash_profile</div><div class="line"># eval &quot;$(pyenv init -)&quot;</div><div class="line">$ exit</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">$ python --version</div><div class="line">Python 3.6.0 :: Anaconda 4.3.1 (x86_64)</div><div class="line">$ pip --version</div><div class="line">pip 9.0.1 from /Users/John/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages (python 3.6)</div><div class="line">$ conda --version</div><div class="line">conda 4.3.14</div></pre></td></tr></table></figure>
<h3 id="CUDA-Installation"><a href="#CUDA-Installation" class="headerlink" title="CUDA Installation"></a>CUDA Installation</h3><a id="more"></a>
<p>For Mac OS X, please see <a href="https://www.tensorflow.org/versions/r0.12/get_started/os_setup.html#optional-setup-gpu-for-mac" target="_blank" rel="external">Setup GPU for Mac</a></p>
<p><a href="https://developer.nvidia.com/cuda-toolkit" target="_blank" rel="external">CUDA Toolkit 8.0</a></p>
<p><a href="https://developer.nvidia.com/cudnn" target="_blank" rel="external">cuDNN v5</a></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ sudo mv include/cudnn.h /Developer/NVIDIA/CUDA-8.0/include/</div><div class="line">$ sudo mv lib/libcudnn* /Developer/NVIDIA/CUDA-8.0/lib</div><div class="line">$ sudo ln -s /Developer/NVIDIA/CUDA-8.0/lib/libcudnn* /usr/local/cuda/lib/</div><div class="line">$ sudo ln -s /usr/local/cuda/lib/libcuda.dylib /usr/local/cuda/lib/libcuda.1.dylib</div></pre></td></tr></table></figure>
<h3 id="OpenCV-Installation"><a href="#OpenCV-Installation" class="headerlink" title="OpenCV Installation"></a>OpenCV Installation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ curl -O https://github.com/opencv/opencv/archive/3.2.0.zip</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line">$ cd opencv</div><div class="line">$ mkdir build</div><div class="line">$ cd build/</div><div class="line">$ PY3_DIR=$HOME/.pyenv/versions/anaconda3-4.3.1 &amp;&amp; \</div><div class="line">export CPLUS_INCLUDE_PATH=$PY3_DIR/include/python3.6m &amp;&amp; \</div><div class="line">cmake -D CMAKE_BUILD_TYPE=RELEASE \</div><div class="line">-D CMAKE_INSTALL_PREFIX=/usr/local \</div><div class="line">-D PYTHON3_LIBRARY=$PY3_DIR/lib \</div><div class="line">-D PYTHON3_INCLUDE_DIR=$PY3_DIR/include/python3.6m \</div><div class="line">-D PYTHON3_EXECUTABLE=$HOME/.pyenv/shims/python \</div><div class="line">-D BUILD_opencv_python2=OFF \</div><div class="line">-D BUILD_opencv_python3=ON \</div><div class="line">-D BUILD_EXAMPLES=ON \</div><div class="line">-D INSTALL_PYTHON_EXAMPLES=OFF \</div><div class="line">-D INSTALL_C_EXAMPLES=OFF \</div><div class="line">..</div><div class="line">$ make -j8</div><div class="line">$ make install</div></pre></td></tr></table></figure>
<p>Issue fixed by <code>export CPLUS_INCLUDE_PATH=$PY3_DIR/include/python3.6m</code>:</p>
<pre><code>[ 73%] Building CXX object modules/python3/CMakeFiles/opencv_python3.dir/__/src2/cv2.cpp.o
/Users/John/Workspace/Fever/Vision/opencv/modules/python/src2/cv2.cpp:6:10: fatal error: &apos;Python.h&apos; file not
      found
#include &lt;Python.h&gt;
         ^
1 error generated.
</code></pre><h2 id="Caffe"><a href="#Caffe" class="headerlink" title="Caffe"></a><a href="http://caffe.berkeleyvision.org/" target="_blank" rel="external">Caffe</a></h2><h3 id="Installation"><a href="#Installation" class="headerlink" title="Installation"></a><a href="http://caffe.berkeleyvision.org/installation.html" target="_blank" rel="external">Installation</a></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ brew install -vd snappy leveldb gflags glog szip lmdb</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"># with Python pycaffe needs dependencies built from source</div><div class="line">$ brew install --build-from-source -vd protobuf --with-python</div><div class="line">$ brew install --build-from-source -vd boost</div><div class="line">$ brew install --build-from-source -vd boost-python --with-python3 --without-python</div></pre></td></tr></table></figure>
<p><a href="http://caffe.berkeleyvision.org/installation.html#compilation" target="_blank" rel="external">Compilation</a></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ git clone https://github.com/BVLC/caffe.git</div><div class="line">$ cd caffe/</div><div class="line">$ git checkout rc5</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ cp Makefile.config.example Makefile.config</div><div class="line"># Adjust Makefile.config (for example, if using Anaconda Python, or if cuDNN is desired)</div></pre></td></tr></table></figure>
<pre><code>USE_CUDNN := 1

OPENCV_VERSION := 3

# brew install openblas
BLAS := open
BLAS_INCLUDE := $(shell brew --prefix openblas)/include
BLAS_LIB := $(shell brew --prefix openblas)/lib

# PYTHON_INCLUDE := /usr/include/python2.7 \
        # /usr/lib/python2.7/dist-packages/numpy/core/include

ANACONDA_HOME := $(HOME)/.pyenv/versions/anaconda3-4.3.1
PYTHON_INCLUDE := $(ANACONDA_HOME)/include \
        $(ANACONDA_HOME)/include/python3.6m \
        $(ANACONDA_HOME)/lib/python3.6/site-packages/numpy/core/include

# ll /usr/local/lib/*boost*py*
PYTHON_LIBRARIES := boost_python3 python3.6m

# PYTHON_LIB := /usr/lib
PYTHON_LIB := $(ANACONDA_HOME)/lib

WITH_PYTHON_LAYER := 1
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ make all -j8</div><div class="line">$ make pycaffe -j8</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">$ vi ~/.bash_profile</div><div class="line"># export PYTHONPATH=$HOME/Workspace/Fever/DeepLearning/caffe/python:$PYTHONPATH</div><div class="line">$ python</div><div class="line">&gt;&gt;&gt; import caffe</div><div class="line">&gt;&gt;&gt; caffe.__version__</div><div class="line">&apos;1.0.0-rc5&apos;</div><div class="line"># Or,</div><div class="line">$ python -c &quot;import caffe; print(caffe.__version__)&quot;</div><div class="line">1.0.0-rc5</div></pre></td></tr></table></figure>
<h3 id="Issues"><a href="#Issues" class="headerlink" title="Issues"></a>Issues</h3><h4 id="Issue-make-pycaffe"><a href="#Issue-make-pycaffe" class="headerlink" title="Issue, make pycaffe:"></a>Issue, <code>make pycaffe</code>:</h4><pre><code>Undefined symbols for architecture x86_64:
  &quot;boost::python::detail::init_module(PyModuleDef&amp;, void (*)())&quot;, referenced from:
      _PyInit__caffe in _caffe-57cf03.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [python/caffe/_caffe.so] Error 1
</code></pre><p>Solution:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ brew info boost-python</div><div class="line">$ brew reinstall boost-python --with-python3 --without-python</div></pre></td></tr></table></figure>
<h4 id="Issue-import-caffe"><a href="#Issue-import-caffe" class="headerlink" title="Issue, import caffe:"></a>Issue, <code>import caffe</code>:</h4><pre><code>&gt;&gt;&gt; import caffe
Failed to include caffe_pb2, things might go wrong!
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
  File &quot;/Users/John/Workspace/Fever/DeepLearning/caffe/python/caffe/__init__.py&quot;, line 4, in &lt;module&gt;
    from .proto.caffe_pb2 import TRAIN, TEST
  File &quot;/Users/John/Workspace/Fever/DeepLearning/caffe/python/caffe/proto/caffe_pb2.py&quot;, line 6, in &lt;module&gt;
    from google.protobuf.internal import enum_type_wrapper
ModuleNotFoundError: No module named &apos;google&apos;
</code></pre><p>Solution:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ pip install protobuf</div></pre></td></tr></table></figure>
<pre><code># https://anaconda.org/anaconda/protobuf/files
$ conda install protobuf
Fetching package metadata .........
Solving package specifications: .

UnsatisfiableError: The following specifications were found to be in conflict:
  - protobuf -&gt; python 2.7* -&gt; openssl 1.0.1*
  - python 3.6*
Use &quot;conda info &lt;package&gt;&quot; to see the dependencies for each package.
</code></pre><h3 id="Others"><a href="#Others" class="headerlink" title="Others"></a>Others</h3><p>How display dependencies:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ cd build/lib/</div><div class="line"># ldd -r libcaffe.so.1.0.0-rc5</div><div class="line">$ otool -L libcaffe.so.1.0.0-rc5</div></pre></td></tr></table></figure>
<h2 id="TensorFlow"><a href="#TensorFlow" class="headerlink" title="TensorFlow"></a><a href="https://www.tensorflow.org/" target="_blank" rel="external">TensorFlow</a></h2><h3 id="Installation-1"><a href="#Installation-1" class="headerlink" title="Installation"></a><a href="https://www.tensorflow.org/versions/r0.12/get_started/os_setup.html#download-and-setup" target="_blank" rel="external">Installation</a></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">$ pip install tensorflow-gpu</div><div class="line"># Or,</div><div class="line"># tensorflow-gpu: https://pypi.python.org/pypi/tensorflow-gpu</div><div class="line">$ export TF_BINARY_URL=https://pypi.python.org/packages/d6/54/f7cf39483b16c25a8c132dc0b81aea2ae91e367da749f17dddeaf739123a/tensorflow_gpu-1.1.0rc1-cp36-cp36m-macosx_10_11_x86_64.whl</div><div class="line">$ pip install --upgrade $TF_BINARY_URL</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">$ python</div><div class="line">...</div><div class="line">&gt;&gt;&gt; import tensorflow as tf</div><div class="line">&gt;&gt;&gt; hello = tf.constant(&apos;Hello, TensorFlow!&apos;)</div><div class="line">&gt;&gt;&gt; sess = tf.Session()</div><div class="line">&gt;&gt;&gt; print(sess.run(hello))</div><div class="line">Hello, TensorFlow!</div><div class="line">&gt;&gt;&gt; a = tf.constant(10)</div><div class="line">&gt;&gt;&gt; b = tf.constant(32)</div><div class="line">&gt;&gt;&gt; print(sess.run(a + b))</div><div class="line">42</div><div class="line">&gt;&gt;&gt;</div></pre></td></tr></table></figure>
<h3 id="Issues-1"><a href="#Issues-1" class="headerlink" title="Issues"></a>Issues</h3><h4 id="Issue-import-tensorflow"><a href="#Issue-import-tensorflow" class="headerlink" title="Issue, import tensorflow:"></a>Issue, <code>import tensorflow</code>:</h4><pre><code>&gt;&gt;&gt; import tensorflow as tf
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcublas.8.0.dylib locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcudnn.5.dylib locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcufft.8.0.dylib locally
Segmentation fault: 11
</code></pre><p>Solution:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ sudo ln -s /usr/local/cuda/lib/libcuda.dylib /usr/local/cuda/lib/libcuda.1.dylib</div></pre></td></tr></table></figure>
<ul>
<li><a href="https://github.com/tensorflow/tensorflow/issues/2940" target="_blank" rel="external">Installing Tensorflow with GPU support on os x 10.11</a></li>
</ul>
<h4 id="Issue-“Library-not-loaded-rpath-libcublas-8-0-dylib”"><a href="#Issue-“Library-not-loaded-rpath-libcublas-8-0-dylib”" class="headerlink" title="Issue, “Library not loaded: @rpath/libcublas.8.0.dylib”:"></a>Issue, “Library not loaded: @rpath/libcublas.8.0.dylib”:</h4><pre><code>ImportError: dlopen(/Users/John/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so, 10): Library not loaded: @rpath/libcublas.8.0.dylib
</code></pre><p>Solution: Disbale <a href="https://support.apple.com/en-us/HT204899" target="_blank" rel="external">SIP</a></p>
<p>Reboot into “Recovery OS”,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ csrutil disable</div></pre></td></tr></table></figure>
<p>Restart into macOS,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ python -c &quot;import tensorflow; print(tensorflow.__version__)&quot;</div><div class="line">1.1.0-rc1</div></pre></td></tr></table></figure>
<h3 id="References"><a href="#References" class="headerlink" title="References"></a>References</h3><ul>
<li><a href="https://github.com/jtoy/awesome-tensorflow" target="_blank" rel="external">Awesome TensorFlow</a></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Requirements&quot;&gt;&lt;a href=&quot;#Requirements&quot; class=&quot;headerlink&quot; title=&quot;Requirements&quot;&gt;&lt;/a&gt;Requirements&lt;/h2&gt;&lt;h3 id=&quot;Python-Installation&quot;&gt;&lt;a href=&quot;#Python-Installation&quot; class=&quot;headerlink&quot; title=&quot;Python Installation&quot;&gt;&lt;/a&gt;Python Installation&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/pyenv/pyenv&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;pyenv&lt;/a&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;7&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ brew install pyenv&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ pyenv install --list&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ pyenv install anaconda3-4.3.1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ pyenv global anaconda3-4.3.1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ pyenv versions&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  system&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;* anaconda3-4.3.1 (set by /Users/John/.pyenv/version)&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Enable pyenv in your shell:&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ vi ~/.bash_profile&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;# eval &amp;quot;$(pyenv init -)&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ exit&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ python --version&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;Python 3.6.0 :: Anaconda 4.3.1 (x86_64)&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ pip --version&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;pip 9.0.1 from /Users/John/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages (python 3.6)&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ conda --version&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;conda 4.3.14&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&quot;CUDA-Installation&quot;&gt;&lt;a href=&quot;#CUDA-Installation&quot; class=&quot;headerlink&quot; title=&quot;CUDA Installation&quot;&gt;&lt;/a&gt;CUDA Installation&lt;/h3&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="Caffe" scheme="http://eevee.cc/tags/Caffe/"/>
    
      <category term="TensorFlow" scheme="http://eevee.cc/tags/TensorFlow/"/>
    
      <category term="Python" scheme="http://eevee.cc/tags/Python/"/>
    
      <category term="CUDA" scheme="http://eevee.cc/tags/CUDA/"/>
    
  </entry>
  
  <entry>
    <title>使用 Djinni 开发 Android, iOS 共享库</title>
    <link href="http://eevee.cc/2016/05/06/using-djinni/"/>
    <id>http://eevee.cc/2016/05/06/using-djinni/</id>
    <published>2016-05-06T07:30:41.000Z</published>
    <updated>2017-05-11T01:25:16.000Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://github.com/dropbox/djinni" target="_blank" rel="external">Djinni</a> 是一个用来生成跨语言的类型声明和接口绑定的工具，主要用于 C++ 和 Java 以及 Objective-C 间的互通。</p>
<p>此文，将介绍如何使用 <a href="https://github.com/dropbox/djinni" target="_blank" rel="external">Djinni</a> 开发 Android, iOS 的共享库。这会带来几个好处：</p>
<ul>
<li>用了接口描述文件。声明清晰、修改简易，并保证了跨平台接口的一致性。</li>
<li>自动生成接口绑定代码。免去了绑定 C++ 和 Java (JNI) 及 Objective-C (Objective-C++) 的麻烦。</li>
</ul>

<style type="text/css">
.post-body .fancybox img { margin: 0 auto 25px; }
</style>

<h2 id="初见：Djinni-及其样例"><a href="#初见：Djinni-及其样例" class="headerlink" title="初见：Djinni 及其样例"></a>初见：Djinni 及其样例</h2><h3 id="下载-Djinni"><a href="#下载-Djinni" class="headerlink" title="下载 Djinni"></a>下载 Djinni</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ git <span class="built_in">clone</span> https://github.com/dropbox/djinni.git</div></pre></td></tr></table></figure>
<h3 id="编译-Djinni"><a href="#编译-Djinni" class="headerlink" title="编译 Djinni"></a>编译 Djinni</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> [djinni_root]/</div><div class="line">$ src/build</div></pre></td></tr></table></figure>
<p>于<code>[djinni_root]/src/support/sbt.resolvers.properties</code>内可添加镜像源。</p>
<ul>
<li><a href="http://www.zhihu.com/question/31158252" target="_blank" rel="external">sbt下载慢？</a></li>
</ul>
<h3 id="使用-Djinni"><a href="#使用-Djinni" class="headerlink" title="使用 Djinni"></a>使用 Djinni</h3><a id="more"></a>
<p>生成样例接口代码：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> [djinni_root]/example/  <span class="comment"># example_root</span></div><div class="line">$ ./run_djinni.sh</div></pre></td></tr></table></figure>
<p>即会生成到<code>djinni-output-temp</code>临时目录，最终复制到<code>generated-src</code>生成目录。</p>
<p>这里可以看到：依据描述文件<code>example.djinni</code>，C++ 和 Java 及 Objective-C 的绑定代码都会自动生成好。继续要做的，只是写它们的具体实现，见样例的<code>handwritten-src</code>目录。</p>
<p>如果要清除输出目录：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ./run_djinni.sh clean</div></pre></td></tr></table></figure>
<h3 id="编译样例"><a href="#编译样例" class="headerlink" title="编译样例"></a>编译样例</h3><p><code>[djinni_root]/Makefile</code>已配置好了依赖，执行相应目标即可。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> [djinni_root]/</div></pre></td></tr></table></figure>
<blockquote>
<p>注：下载好 Djinni ，即可开始编译样例了。</p>
</blockquote>
<p>编译 Android 工程：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ make example_android</div></pre></td></tr></table></figure>
<p>样例的 Android 工程在<code>[example_root]/android</code>目录， 动态库生成在<code>[example_root]/android/app/libs</code>目录。或者，利用 Android Studio / Gradle 来运行编译。</p>
<p>编译 iOS 工程：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ make example_ios</div></pre></td></tr></table></figure>
<p>样例的 iOS 工程在<code>[example_root]/objc</code>目录， lib 工程生成在<code>[djinni_root]\build_ios</code>目录。然后，可以打开<code>[example_root]/objc/TextSort.xcworkspace</code>来运行编译。</p>
<p>如果要清理工程：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ make clean</div></pre></td></tr></table></figure>
<h3 id="准备-GYP"><a href="#准备-GYP" class="headerlink" title="准备 GYP"></a>准备 GYP</h3><p>编译样例时， Android NDK 与 iOS 的 Library 工程都需依赖 GYP 生成。 make 时，会自行 clone 到<code>[djinni_root]/deps/gyp</code>目录。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ git <span class="built_in">clone</span> https://chromium.googlesource.com/external/gyp.git</div></pre></td></tr></table></figure>
<p>GYP 生成 Android Makefile 时，目前会遇到如下错误：</p>
<blockquote>
<p>ImportError: No module named android</p>
</blockquote>
<p>所以，需要切换到旧版本。此后的那个 commit 移除了 Android 的生成器。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ cd gyp/</div><div class="line">$ git checkout -q 0bb67471bca068996e15b56738fa4824dfa19de0</div></pre></td></tr></table></figure>
<blockquote>
<p>注：<a href="https://github.com/dropbox/djinni/issues/87" target="_blank" rel="external">Stop using gyp’s android generator</a></p>
</blockquote>
<h2 id="从无到有：Hello-Djinni"><a href="#从无到有：Hello-Djinni" class="headerlink" title="从无到有：Hello Djinni"></a>从无到有：Hello Djinni</h2><h3 id="C-接口"><a href="#C-接口" class="headerlink" title="C++ 接口"></a>C++ 接口</h3><h4 id="定义接口描述文件"><a href="#定义接口描述文件" class="headerlink" title="定义接口描述文件"></a>定义接口描述文件</h4><figure class="highlight bash"><figcaption><span>hellodjinni.djinni</span><a href="https://github.com/joinAero/XCalculator/blob/master/sample/hellodjinni/hellodjinni.djinni" target="_blank" rel="external">hellodjinni.djinni</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">hello_djinni = interface +c &#123;</div><div class="line">    static create(): hello_djinni;</div><div class="line">    get_hello_djinni(): string;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h4 id="生成接口绑定代码"><a href="#生成接口绑定代码" class="headerlink" title="生成接口绑定代码"></a>生成接口绑定代码</h4><p>写了个简单的 Shell 脚本来执行 Djinni 命令，如下：</p>
<figure class="highlight bash"><figcaption><span>run_djinni.sh:</span><a href="https://github.com/joinAero/XCalculator/blob/master/sample/hellodjinni/run_djinni.sh" target="_blank" rel="external">run_djinni.sh</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line"><span class="built_in">set</span> <span class="_">-e</span></div><div class="line"><span class="built_in">shopt</span> <span class="_">-s</span> nullglob</div><div class="line"></div><div class="line">base_dir=$(<span class="built_in">cd</span> <span class="string">"`dirname "</span><span class="variable">$0</span><span class="string">"`"</span> &amp;&amp; <span class="built_in">pwd</span>)</div><div class="line"></div><div class="line"><span class="comment"># Read local properties</span></div><div class="line"><span class="built_in">eval</span> $(cat <span class="variable">$base_dir</span>/local.properties | sed <span class="string">'s/&lt;[^&gt;]*&gt;//g'</span> | sed <span class="string">'s/\./_/g'</span>)</div><div class="line"><span class="keyword">if</span> [[ -z <span class="variable">$djinni_dir</span> ]]; <span class="keyword">then</span></div><div class="line">    <span class="built_in">echo</span> <span class="string">"Unspecified djinni.dir in local.properties"</span> 1&gt;&amp;2</div><div class="line">    <span class="built_in">exit</span> 1</div><div class="line"><span class="keyword">fi</span></div><div class="line"></div><div class="line"></div><div class="line">out_dir=<span class="string">"<span class="variable">$base_dir</span>/generated-src"</span></div><div class="line"></div><div class="line">cpp_out=<span class="string">"<span class="variable">$out_dir</span>/cpp"</span></div><div class="line">jni_out=<span class="string">"<span class="variable">$out_dir</span>/jni"</span></div><div class="line">objc_out=<span class="string">"<span class="variable">$out_dir</span>/objc"</span></div><div class="line">java_out=<span class="string">"<span class="variable">$out_dir</span>/java/cc/eevee/hellodjinni"</span></div><div class="line"></div><div class="line">java_package=<span class="string">"cc.eevee.hellodjinni"</span></div><div class="line">cpp_namespace=<span class="string">"hellodjinni"</span></div><div class="line">objc_type_prefix=<span class="string">"HD"</span></div><div class="line">djinni_file=<span class="string">"<span class="variable">$base_dir</span>/hellodjinni.djinni"</span></div><div class="line"></div><div class="line"></div><div class="line">[[ <span class="_">-e</span> <span class="variable">$out_dir</span> ]] &amp;&amp; rm -rf <span class="variable">$out_dir</span></div><div class="line"></div><div class="line"><span class="variable">$djinni_dir</span>/src/run-assume-built \</div><div class="line">    --java-out <span class="variable">$java_out</span> \</div><div class="line">    --java-package <span class="variable">$java_package</span> \</div><div class="line">    --ident-java-field mFooBar \</div><div class="line">    \</div><div class="line">    --cpp-out <span class="variable">$cpp_out</span> \</div><div class="line">    --cpp-namespace <span class="variable">$cpp_namespace</span> \</div><div class="line">    \</div><div class="line">    --jni-out <span class="variable">$jni_out</span> \</div><div class="line">    --ident-jni-class NativeFooBar \</div><div class="line">    --ident-jni-file NativeFooBar \</div><div class="line">    \</div><div class="line">    --objc-out <span class="variable">$objc_out</span> \</div><div class="line">    --objcpp-out <span class="variable">$objc_out</span> \</div><div class="line">    --objc-type-prefix <span class="variable">$objc_type_prefix</span> \</div><div class="line">    \</div><div class="line">    --idl <span class="variable">$djinni_file</span></div></pre></td></tr></table></figure>
<p>其读取了<code>local.properties</code>内配置的 Djinni 目录路径。</p>
<figure class="highlight bash"><figcaption><span>local.properties</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/local.properties" target="_blank" rel="external">local.properties</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">djinni.dir=&lt;path-to-djinni&gt;</div><div class="line">gyp.dir=&lt;path-to-gyp&gt;</div><div class="line">ndk.dir=&lt;path-to-ndk&gt;</div></pre></td></tr></table></figure>
<p>运行后，代码生成在了<code>generated-src</code>目录。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ./run_djinni.sh</div></pre></td></tr></table></figure>
<h4 id="实现-C-接口"><a href="#实现-C-接口" class="headerlink" title="实现 C++ 接口"></a>实现 C++ 接口</h4><p>首先，创建<code>src</code>目录，存放手写的代码。然后，于子目录<code>cpp</code>内实现 C++ 接口。</p>
<figure class="highlight hpp"><figcaption><span>src/cpp/hello_djinni_impl.hpp</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/src/cpp/hello_djinni_impl.hpp" target="_blank" rel="external">hello_djinni_impl.hpp</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">pragma</span> once</span></div><div class="line"></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"hello_djinni.hpp"</span></span></div><div class="line"></div><div class="line"><span class="keyword">namespace</span> hellodjinni &#123;</div><div class="line"></div><div class="line"><span class="keyword">class</span> HelloDjinniImpl : <span class="keyword">public</span> HelloDjinni &#123;</div><div class="line"><span class="keyword">public</span>:</div><div class="line">    <span class="comment">// Constructor</span></div><div class="line">    HelloDjinniImpl();</div><div class="line"></div><div class="line">    <span class="comment">// Our method that returns a string</span></div><div class="line">    <span class="built_in">std</span>::<span class="function"><span class="built_in">string</span> <span class="title">get_hello_djinni</span><span class="params">()</span></span>;</div><div class="line">&#125;;</div><div class="line"></div><div class="line">&#125;  <span class="comment">// namespace hellodjinni</span></div></pre></td></tr></table></figure>
<figure class="highlight cpp"><figcaption><span>src/cpp/hello_djinni_impl.cpp</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/src/cpp/hello_djinni_impl.cpp" target="_blank" rel="external">hello_djinni_impl.cpp</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"hello_djinni_impl.hpp"</span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></div><div class="line"></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> hellodjinni;</div><div class="line"></div><div class="line"><span class="built_in">std</span>::<span class="built_in">shared_ptr</span>&lt;HelloDjinni&gt; HelloDjinni::create() &#123;</div><div class="line">    <span class="keyword">return</span> <span class="built_in">std</span>::make_shared&lt;HelloDjinniImpl&gt;();</div><div class="line">&#125;</div><div class="line"></div><div class="line">HelloDjinniImpl::HelloDjinniImpl() &#123;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="built_in">std</span>::<span class="built_in">string</span> HelloDjinniImpl::get_hello_djinni() &#123;</div><div class="line">    <span class="built_in">std</span>::<span class="built_in">string</span> result = <span class="string">"Hello Djinni! "</span>;</div><div class="line"></div><div class="line">    <span class="keyword">time_t</span> t = time(<span class="number">0</span>);</div><div class="line">    tm now = *localtime(&amp;t);</div><div class="line"></div><div class="line">    <span class="keyword">char</span> tm_desc[<span class="number">200</span>] = &#123;<span class="number">0</span>&#125;;</div><div class="line">    <span class="keyword">if</span> (strftime(tm_desc, <span class="keyword">sizeof</span>(tm_desc)<span class="number">-1</span>, <span class="string">"%r"</span>, &amp;now)&gt;<span class="number">0</span>) &#123;</div><div class="line">        result += tm_desc;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="keyword">return</span> result;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h3 id="C-工程"><a href="#C-工程" class="headerlink" title="C++ 工程"></a>C++ 工程</h3><p>这里用 XCode 创建一个 C++ 工程，来测试 C++ 接口代码。</p>
<p>首先，打开 XCode ，选择”Create a new Xcode project”。然后，选择”Command Line Tool”，来新建命令行工具。</p>
<img src="/2016/05/06/using-djinni/cpp_pro_new.png" alt="cpp_pro_new.png" title="">
<p>“Next”到下一步时，”Language”选择”C++”。</p>
<img src="/2016/05/06/using-djinni/cpp_pro_new_2.png" alt="cpp_pro_new_2.png" title="">
<p>工程最后保存到了<code>project/cpp</code>目录。整个文件结构如下：</p>
<img src="/2016/05/06/using-djinni/cpp_pro_structure.png" width="240">
<p>接下来，把以下 C++ 接口代码文件，拖动到 XCode 工程目录来引入。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">generated-src/cpp/hello_djinni.hpp</div><div class="line">src/cpp/hello_djinni_impl.cpp</div><div class="line">src/cpp/hello_djinni_impl.hpp</div></pre></td></tr></table></figure>
<blockquote>
<p>注：取消”Copy items if needed”，选择”Create folder references”。只需引用文件，避免复制。</p>
</blockquote>
<img src="/2016/05/06/using-djinni/cpp_pro_move.png" alt="cpp_pro_move.png" title="">
<p>然后，编写好<code>main.cpp</code>的代码：</p>
<figure class="highlight cpp"><figcaption><span>project/cpp/HelloDjinni/HelloDjinni/main.cpp</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/cpp/HelloDjinni/HelloDjinni/main.cpp" target="_blank" rel="external">main.cpp</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"hello_djinni_impl.hpp"</span></span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">const</span> <span class="keyword">char</span> * argv[])</span> </span>&#123;</div><div class="line">    <span class="keyword">typedef</span> hellodjinni::HelloDjinni HelloDjinni;</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> hd = HelloDjinni::create();</div><div class="line">    <span class="keyword">auto</span> result = hd-&gt;get_hello_djinni();</div><div class="line">    <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; result &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</div><div class="line"></div><div class="line">    <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>最后，运行项目，结果如下：</p>
<img src="/2016/05/06/using-djinni/cpp_pro_overview.png" alt="cpp_pro_overview.png" title="">
<p>或者，写个<code>project/Cpp.mk</code>：</p>
<figure class="highlight makefile"><figcaption><span>project/Cpp.mk</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/Cpp.mk" target="_blank" rel="external">Cpp.mk</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div></pre></td><td class="code"><pre><div class="line">MD := -mkdir -p</div><div class="line">RD := -rm -rf</div><div class="line">RM := -rm -f</div><div class="line"></div><div class="line">CC := gcc</div><div class="line">CXX := g++</div><div class="line">CXXFLAGS := -std=c++11 -Wall</div><div class="line"></div><div class="line">ifdef DEBUG</div><div class="line">CXXFLAGS += -g -DDEBUG</div><div class="line">else</div><div class="line">CXXFLAGS += -O2 -DNDEBUG</div><div class="line">endif</div><div class="line"></div><div class="line">OUT_DIR ?= build</div><div class="line">CPP_OUT ?= <span class="variable">$(OUT_DIR)</span>/cpp</div><div class="line"></div><div class="line">CPP_INCLUDES := \</div><div class="line">    ../generated-src/cpp \</div><div class="line">    ../src/cpp</div><div class="line">CPP_SOURCES := \</div><div class="line">    ../src/cpp/hello_djinni_impl.cpp \</div><div class="line">    cpp/HelloDjinni/HelloDjinni/main.cpp</div><div class="line">CPP_TARGET := <span class="variable">$(CPP_OUT)</span>/HelloDjinni</div><div class="line"></div><div class="line"></div><div class="line">all: cpp_pro</div><div class="line"></div><div class="line"><span class="section">clean:</span></div><div class="line">    $(RD) $(CPP_OUT)/</div><div class="line"></div><div class="line">cpp_pro: $(CPP_SOURCES)</div><div class="line">    @echo "\033[1;35;47mBuild cpp project...\033[0m"</div><div class="line">    @$(MD) $(CPP_OUT)</div><div class="line">    $(CXX) $(CXXFLAGS) $(CPP_SOURCES) -o $(CPP_TARGET) \</div><div class="line">        $(foreach d, $(CPP_INCLUDES), -I$d)</div><div class="line">    @echo "\033[32mOutput:\033[0m\n$(CPP_TARGET)"</div><div class="line">    @echo "\033[32mRunning:\033[0m"</div><div class="line">    @$(CPP_TARGET)</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: cpp_pro clean all</span></div></pre></td></tr></table></figure>
<p>然后，<code>make -f Cpp.mk</code>编译运行，结果如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">Build cpp project...</div><div class="line">g++ -std=c++11 -Wall -O2 -DNDEBUG \</div><div class="line">    ../src/cpp/hello_djinni_impl.cpp \</div><div class="line">    cpp/HelloDjinni/HelloDjinni/main.cpp \</div><div class="line">    -o build/cpp/HelloDjinni \</div><div class="line">    -I../generated-src/cpp -I../src/cpp</div><div class="line">Output:</div><div class="line">build/cpp/HelloDjinni</div><div class="line">Running:</div><div class="line">Hello Djinni! 11:46:56 PM</div></pre></td></tr></table></figure>
<h3 id="iOS-工程"><a href="#iOS-工程" class="headerlink" title="iOS 工程"></a>iOS 工程</h3><p>打开 XCode，”File &gt; New &gt; Workspace”新建一个工作区，保存到<code>project/ios</code>目录。</p>
<p>接着，”File &gt; New &gt; Project”，选择”Single View Application”，创建 iOS 工程。</p>
<img src="/2016/05/06/using-djinni/ios_pro_new.png" alt="ios_pro_new.png" title="">
<p>“Next”到下一步时，”Language”选择”Objective-C”。</p>
<img src="/2016/05/06/using-djinni/ios_pro_new_2.png" alt="ios_pro_new_2.png" title="">
<p>工程保存到<code>project/ios</code>目录，”Add to”选择刚才的工作区。</p>
<img src="/2016/05/06/using-djinni/ios_pro_new_3.png" alt="ios_pro_new_3.png" title="">
<p>“Create”完成创建。</p>
<h4 id="生成接口-Libraries-工程"><a href="#生成接口-Libraries-工程" class="headerlink" title="生成接口 Libraries 工程"></a>生成接口 Libraries 工程</h4><p>利用 Djinni, GYP 及 Make 生成接口 Libraries 工程。</p>
<p>首先，创建 GYP 文件：</p>
<figure class="highlight json"><figcaption><span>project/libhellodjinni.gyp</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/libhellodjinni.gyp" target="_blank" rel="external">libhellodjinni.gyp</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">  <span class="attr">"targets"</span>: [</div><div class="line">    &#123;</div><div class="line">      <span class="attr">"target_name"</span>: <span class="string">"libhellodjinni_jni"</span>,</div><div class="line">      <span class="attr">"type"</span>: <span class="string">"shared_library"</span>,</div><div class="line">      <span class="attr">"dependencies"</span>: [</div><div class="line">        <span class="string">"&lt;(DJINNI_DIR)/support-lib/support_lib.gyp:djinni_jni"</span>,</div><div class="line">      ],</div><div class="line">      <span class="attr">"ldflags"</span>: [ <span class="string">"-llog"</span>, <span class="string">"-Wl,--build-id,--gc-sections,--exclude-libs,ALL"</span> ],</div><div class="line">      <span class="attr">"sources"</span>: [</div><div class="line">        <span class="string">"&lt;(DJINNI_DIR)/support-lib/jni/djinni_main.cpp"</span>,</div><div class="line">        <span class="string">"&lt;!@(python &lt;(DJINNI_DIR)/example/glob.py ../generated-src/jni '*.cpp')"</span>,</div><div class="line">        <span class="string">"&lt;!@(python &lt;(DJINNI_DIR)/example/glob.py ../generated-src/cpp '*.cpp')"</span>,</div><div class="line">        <span class="string">"&lt;!@(python &lt;(DJINNI_DIR)/example/glob.py ../src '*.cpp')"</span>,</div><div class="line">      ],</div><div class="line">      <span class="attr">"include_dirs"</span>: [</div><div class="line">        <span class="string">"../generated-src/jni"</span>,</div><div class="line">        <span class="string">"../generated-src/cpp"</span>,</div><div class="line">        <span class="string">"../src/cpp"</span>,</div><div class="line">      ],</div><div class="line">    &#125;,</div><div class="line">    &#123;</div><div class="line">      <span class="attr">"target_name"</span>: <span class="string">"libhellodjinni_objc"</span>,</div><div class="line">      <span class="attr">"type"</span>: <span class="string">"static_library"</span>,</div><div class="line">      <span class="attr">"dependencies"</span>: [</div><div class="line">        <span class="string">"&lt;(DJINNI_DIR)/support-lib/support_lib.gyp:djinni_objc"</span>,</div><div class="line">      ],</div><div class="line">      <span class="attr">"sources"</span>: [</div><div class="line">        <span class="string">"&lt;!@(python &lt;(DJINNI_DIR)/example/glob.py ../generated-src/objc '*.cpp' '*.mm' '*.m')"</span>,</div><div class="line">        <span class="string">"&lt;!@(python &lt;(DJINNI_DIR)/example/glob.py ../generated-src/cpp  '*.cpp')"</span>,</div><div class="line">        <span class="string">"&lt;!@(python &lt;(DJINNI_DIR)/example/glob.py ../src '*.cpp')"</span>,</div><div class="line">      ],</div><div class="line">      <span class="attr">"include_dirs"</span>: [</div><div class="line">        <span class="string">"../generated-src/objc"</span>,</div><div class="line">        <span class="string">"../generated-src/cpp"</span>,</div><div class="line">        <span class="string">"../src/cpp"</span>,</div><div class="line">      ],</div><div class="line">    &#125;,</div><div class="line">  ],</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<blockquote>
<p>注意：<br>1) <code>sources</code>内的路径必须是相对路径。虽然会识别以<code>/</code>开头的字符串为绝对路径，但在 XCode 工程内其路径引用是不正确的。<br>2) GYP 生成 Android Makefile 时，运行命令时的工作目录，必须能够直接子目录到所有代码，包括依赖的 Djinni 的 support-lib 。不然，会报如下错误：</p>
<blockquote>
<p>AssertionError: Path %s attempts to escape from gyp path %s !)</p>
</blockquote>
<p>👌的话，<code>GypAndroid.mk</code>会生成到当前工作目录。GYP 生成 Android 时，不允许指定<code>--generator-output</code>：</p>
<blockquote>
<p>AssertionError: The Android backend does not support options.generator_output.</p>
</blockquote>
</blockquote>
<p>所以，简单的解决办法是，文件结构与<code>[djinni_root]/example</code>一致，并<code>git submodule</code> Djinni 与 GYP 到工程目录内。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ git init</div><div class="line">$ git submodule add https://github.com/dropbox/djinni.git deps/djinni</div><div class="line">$ git submodule add https://chromium.googlesource.com/external/gyp.git deps/gyp</div></pre></td></tr></table></figure>
<p>如果仍想要 Djinni 与 GYP 独立于工程目录外，同时又能够工作在工程目录，那么需要把依赖的东西复制进工程目录。之后，即是这样做的。</p>
<p>接下来，创建 Makefile 文件：</p>
<figure class="highlight makefile"><figcaption><span>project/Makefile</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/Makefile" target="_blank" rel="external">Makefile</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div></pre></td><td class="code"><pre><div class="line">MD := -mkdir -p</div><div class="line">RD := -rm -rf</div><div class="line">RM := -rm -f</div><div class="line"></div><div class="line">SED_PROP := "s/&lt;[^&gt;]*&gt;//g;s/.*=\(.*\)/\1/"</div><div class="line"></div><div class="line">define read_prop</div><div class="line">    $(eval $(1) := $(shell ../tools/read_properties.sh \</div><div class="line">        | grep -m1 $(2) | sed $(SED_PROP)))</div><div class="line">endef</div><div class="line"></div><div class="line">$(call read_prop,GYP_DIR,gyp_dir)</div><div class="line">$(call read_prop,NDK_DIR,ndk_dir)</div><div class="line"></div><div class="line"></div><div class="line">OUT_DIR ?= build</div><div class="line">IOS_OUT ?= <span class="variable">$(OUT_DIR)</span>/ios</div><div class="line"></div><div class="line">DEPS_DIR ?= deps</div><div class="line">DEPS_DJINNI_DIR := <span class="variable">$(DEPS_DIR)</span>/djinni</div><div class="line"></div><div class="line">DJINNI_OUT_DIR ?= ../generated-src</div><div class="line"></div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: all</span></div><div class="line">all: cpp_pro ios_pro android_pro android_pro2</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: clean</span></div><div class="line"><span class="section">clean:</span></div><div class="line">    @make ios_pro_clean</div><div class="line">    @make android_pro_clean</div><div class="line">    @make android_pro2_clean</div><div class="line">    @echo "\033[1;35;47mClean others...\033[0m"</div><div class="line">    $(RD) $(OUT_DIR)/</div><div class="line">    $(RD) $(DEPS_DIR)/</div><div class="line">    $(RD) $(DJINNI_OUT_DIR)/</div><div class="line">    $(RM) ../GypAndroid.mk</div><div class="line">    $(RM) libhellodjinni_jni.target.mk</div><div class="line">    @<span class="comment"># @make cpp_pro_clean</span></div><div class="line"></div><div class="line"><span class="section">deps:</span></div><div class="line">    @echo "\033[1;35;47mPrepare dependencies...\033[0m"</div><div class="line">    @../tools/prepare_deps.sh $(DEPS_DIR)</div><div class="line"></div><div class="line">$(DJINNI_OUT_DIR): ../hellodjinni.djinni</div><div class="line">    @echo "\033[1;35;47mGenerate djinni interface code...\033[0m"</div><div class="line">    @../run_djinni.sh</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: djinni</span></div><div class="line">djinni: $(DJINNI_OUT_DIR)</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: cpp_pro</span></div><div class="line">cpp_pro: $(DJINNI_OUT_DIR)</div><div class="line">    @make -f Cpp.mk cpp_pro</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: cpp_pro_clean</span></div><div class="line"><span class="section">cpp_pro_clean:</span></div><div class="line">    @make -f Cpp.mk clean</div><div class="line"></div><div class="line">$(IOS_OUT)/libhellodjinni.xcodeproj: deps $(DJINNI_OUT_DIR) libhellodjinni.gyp \</div><div class="line">        $(DEPS_DJINNI_DIR)/support-lib/support_lib.gyp</div><div class="line">    @echo "\033[1;35;47mGenerate libhellodjinni.xcodeproj...\033[0m"</div><div class="line">    @$(GYP_DIR)/gyp --depth=. -f xcode -DOS=ios \</div><div class="line">        --generator-output $(IOS_OUT) \</div><div class="line">        -DDJINNI_DIR=$(DEPS_DJINNI_DIR) \</div><div class="line">        -I$(DEPS_DJINNI_DIR)/common.gypi \</div><div class="line">        libhellodjinni.gyp</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: ios_pro</span></div><div class="line">ios_pro: $(IOS_OUT)/libhellodjinni.xcodeproj</div><div class="line">    @echo "\033[1;35;47mBuild ios project...\033[0m"</div><div class="line">    xcodebuild -workspace ios/HelloDjinni.xcworkspace \</div><div class="line">        -scheme HelloDjinni -configuration 'Debug' -sdk iphonesimulator</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: ios_pro_clean</span></div><div class="line"><span class="section">ios_pro_clean:</span></div><div class="line">    @echo "\033[1;35;47mClean ios project...\033[0m"</div><div class="line">    @-xcodebuild -workspace ios/HelloDjinni.xcworkspace \</div><div class="line">        -scheme HelloDjinni -configuration 'Debug' -sdk iphonesimulator clean</div><div class="line"></div><div class="line">../GypAndroid.mk: deps $(DJINNI_OUT_DIR) libhellodjinni.gyp \</div><div class="line">        $(DEPS_DJINNI_DIR)/support-lib/support_lib.gyp</div><div class="line">    @echo "\033[1;35;47mGenerate GypAndroid.mk...\033[0m"</div><div class="line">    @make gyp_android</div><div class="line">    @cd .. &amp;&amp; ANDROID_BUILD_TOP=$(NDK_DIR) \</div><div class="line">        $(GYP_DIR)/gyp --depth=. -f android -DOS=android \</div><div class="line">        -DDJINNI_DIR=$(DEPS_DJINNI_DIR) \</div><div class="line">        -Iproject/$(DEPS_DJINNI_DIR)/common.gypi \</div><div class="line">        project/libhellodjinni.gyp \</div><div class="line">        --root-target=libhellodjinni_jni</div><div class="line">    @make gyp_master</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: android_pro</span></div><div class="line">android_pro: ../GypAndroid.mk</div><div class="line">    @echo "\033[1;35;47mBuild android project (HelloDjinni)...\033[0m"</div><div class="line">    cd android/HelloDjinni/ &amp;&amp; ./gradlew app:assembleDebug</div><div class="line">    @echo "\033[32mApks produced at:\033[0m"</div><div class="line">    @python $(DEPS_DJINNI_DIR)/example/glob.py \</div><div class="line">        android/HelloDjinni/app/build/outputs/apk/ '*.apk'</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: android_pro_clean</span></div><div class="line">android_pro_clean: ../GypAndroid.mk</div><div class="line">    @echo "\033[1;35;47mClean android project (HelloDjinni)...\033[0m"</div><div class="line">    @ndk-build -C android/HelloDjinni/app-core clean</div><div class="line">    @-cd android/HelloDjinni/ &amp;&amp; ./gradlew clean</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: android_pro2</span></div><div class="line">android_pro2: deps djinni libhellodjinni.gyp \</div><div class="line">        $(DEPS_DJINNI_DIR)/support-lib/support_lib.gyp</div><div class="line">    @echo "\033[1;35;47mBuild android project (HelloDjinni2)...\033[0m"</div><div class="line">    cd android/HelloDjinni2/ &amp;&amp; ./gradlew app:assembleDebug</div><div class="line">    @echo "\033[32mApks produced at:\033[0m"</div><div class="line">    @python $(DEPS_DJINNI_DIR)/example/glob.py \</div><div class="line">        android/HelloDjinni2/app/build/outputs/apk/ '*.apk'</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: android_pro2_clean</span></div><div class="line"><span class="section">android_pro2_clean:</span></div><div class="line">    @echo "\033[1;35;47mClean android project (HelloDjinni2)...\033[0m"</div><div class="line">    @-cd android/HelloDjinni2/ &amp;&amp; ./gradlew clean</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: gyp_status</span></div><div class="line"><span class="section">gyp_status:</span></div><div class="line">    @cd $(GYP_DIR) &amp;&amp; git status</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: gyp_master</span></div><div class="line"><span class="section">gyp_master:</span></div><div class="line">    @echo "\033[1;35;47mCheckout gyp to master...\033[0m"</div><div class="line">    @cd $(GYP_DIR) &amp;&amp; git checkout master</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: gyp_android</span></div><div class="line"><span class="section">gyp_android:</span></div><div class="line">    @echo "\033[1;35;47mCheckout gyp to android generator...\033[0m"</div><div class="line">    @cd $(GYP_DIR) &amp;&amp; git checkout -q 0bb67471bca068996e15b56738fa4824dfa19de0</div><div class="line"></div><div class="line"><span class="meta"><span class="meta-keyword">.PHONY</span>: test_vars</span></div><div class="line"><span class="section">test_vars:</span></div><div class="line">    @echo "\033[1;35;47mPrint variables...\033[0m"</div><div class="line">    @echo GYP_DIR=$(GYP_DIR)</div><div class="line">    @echo NDK_DIR=$(NDK_DIR)</div><div class="line">    @echo OUT_DIR=$(OUT_DIR)</div><div class="line">    @echo IOS_OUT=$(IOS_OUT)</div><div class="line">    @echo DEPS_DIR=$(DEPS_DIR)</div><div class="line">    @echo DEPS_DJINNI_DIR=$(DEPS_DJINNI_DIR)</div></pre></td></tr></table></figure>
<p>其也包括了 Android 工程的配置。</p>
<blockquote>
<p>注：额外依赖了两个辅助脚本，说明如下：<br><code>read_properties.sh</code>，读取<code>local.properties</code>内配置的路径。<br><code>prepare_deps.sh</code>，准备依赖的文件到指定目录。</p>
</blockquote>
<p>然后，运行生成 XCode 的 libhellodjinni 工程。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> project/</div><div class="line">$ make ios_pro</div></pre></td></tr></table></figure>
<p>其生成在<code>project/build/ios</code>目录。 XCode 直接打开<code>libhellodjinni.xcodeproj</code>，即可选择目标进行编译。</p>
<p>但可能此时 libhellodjinni_jni 与 djinni_jni (support_lib) 目标，不能够找到<code>jni.h</code>。由于 ios 上不需要 jni 绑定，后续也不需依赖，没多大影响。</p>
<p>也让其可通过编译的话，只需要选择目标，在”Build Settings &gt; Header Search Paths”内，添加 Java VM include 就好。</p>
<p>运行如下命令，获得当前的 Java 头文件路径：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ls <span class="_">-l</span> `<span class="built_in">which</span> java` | sed <span class="string">'s/^.*-&gt; *\(.*Current\).*$/\1\/Headers/;q'</span></div></pre></td></tr></table></figure>
<p>结果，如：”/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers”。</p>
<p>或者，这里找：”/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/include/“。</p>
<img src="/2016/05/06/using-djinni/ios_pro_lib_header.png" alt="ios_pro_lib_header.png" title="">
<h4 id="添加接口-Libraries-依赖"><a href="#添加接口-Libraries-依赖" class="headerlink" title="添加接口 Libraries 依赖"></a>添加接口 Libraries 依赖</h4><p>现在，给 iOS 工程上添加上接口 Libraries 的依赖。</p>
<p>首先，打开先前的工作区<code>project/ios/HelloDjinni.xcworkspace</code>。于左侧项目导航的灰色区域，”Ctrl+Click”或右击打开菜单。选择”Add Files to “HelloDjinni””，添加生成好的<code>libhellodjinni.xcodeproj</code>和<code>support_lib.xcodeproj</code>两个库工程。</p>
<p>之后，项目导航选中”HelloDjinni”工程，并选择”HelloDjinni”目标。在”Build Phases”标签页的”Link Binaries With Libraries”选项下，新增 libhellodjinni_objc.a 与 libdjinni_objc.a 的依赖，如下：</p>
<img src="/2016/05/06/using-djinni/ios_pro_lib_link.png" alt="ios_pro_lib_link.png" title="">
<p>在”Build Settings”标签页，找到”Header Search Paths”，添加头文件搜索路径：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$(SRCROOT)/../../deps/djinni/support-lib/objc</div><div class="line">$(SRCROOT)/../../../generated-src/objc</div></pre></td></tr></table></figure>
<p>为了兼容 Objective-C++ 桥接代码，需要将<code>HelloWorld/Supporting Files/main.m</code>重命名为<code>main.mm</code>。</p>
<p>最终，工作区会类似于下面这样：</p>
<img src="/2016/05/06/using-djinni/ios_pro_overview.png" alt="ios_pro_overview.png" title="">
<h4 id="完成-UI-并运行"><a href="#完成-UI-并运行" class="headerlink" title="完成 UI 并运行"></a>完成 UI 并运行</h4><p>于<code>ViewController.m</code>内编写代码，创建 UI 并调用接口代码。</p>
<figure class="highlight objc"><figcaption><span>project/ios/HelloDjinni/HelloDjinni/ViewController.m</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/ios/HelloDjinni/HelloDjinni/ViewController.m" target="_blank" rel="external">ViewController.m</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#import <span class="meta-string">"ViewController.h"</span></span></div><div class="line"><span class="meta">#import <span class="meta-string">"HDHelloDjinni.h"</span></span></div><div class="line"></div><div class="line"><span class="class"><span class="keyword">@interface</span> <span class="title">ViewController</span> ()</span></div><div class="line"></div><div class="line"><span class="keyword">@end</span></div><div class="line"></div><div class="line"><span class="class"><span class="keyword">@implementation</span> <span class="title">ViewController</span> </span>&#123;</div><div class="line">    HDHelloDjinni *_helloDjinniInterface;</div><div class="line">    <span class="built_in">UIButton</span> *_button;</div><div class="line">    <span class="built_in">UITextView</span> *_textView;</div><div class="line">&#125;</div><div class="line"></div><div class="line">- (<span class="keyword">void</span>)viewDidLoad &#123;</div><div class="line">    [<span class="keyword">super</span> viewDidLoad];</div><div class="line"></div><div class="line">    <span class="comment">// instantiate our library interface</span></div><div class="line">    _helloDjinniInterface = [HDHelloDjinni create];</div><div class="line"></div><div class="line">    <span class="comment">// create a button programatically for the demo</span></div><div class="line">    _button = [<span class="built_in">UIButton</span> buttonWithType:<span class="built_in">UIButtonTypeRoundedRect</span>];</div><div class="line">    [_button addTarget:<span class="keyword">self</span></div><div class="line">                action:<span class="keyword">@selector</span>(buttonWasPressed:)</div><div class="line">      forControlEvents:<span class="built_in">UIControlEventTouchUpInside</span>];</div><div class="line">    [_button setTitle:<span class="string">@"Get Hello Djinni!"</span> forState:<span class="built_in">UIControlStateNormal</span>];</div><div class="line">    _button.frame = <span class="built_in">CGRectMake</span>(<span class="number">20.0</span>, <span class="number">20.0</span>, <span class="number">280.0</span>, <span class="number">40.0</span>);</div><div class="line">    [<span class="keyword">self</span>.view addSubview:_button];</div><div class="line"></div><div class="line">    <span class="comment">// create a text view programatically</span></div><div class="line">    _textView = [[<span class="built_in">UITextView</span> alloc] init];</div><div class="line">    <span class="comment">// x, y, width, height</span></div><div class="line">    _textView.frame = <span class="built_in">CGRectMake</span>(<span class="number">20.0</span>, <span class="number">80.0</span>, <span class="number">280.0</span>, <span class="number">380.0</span>);</div><div class="line">    [<span class="keyword">self</span>.view addSubview:_textView];</div><div class="line">&#125;</div><div class="line"></div><div class="line">- (<span class="keyword">void</span>)buttonWasPressed:(<span class="built_in">UIButton</span> *)sender &#123;</div><div class="line">    <span class="built_in">NSString</span> *response = [_helloDjinniInterface getHelloDjinni];</div><div class="line">    _textView.text = [<span class="built_in">NSString</span> stringWithFormat:<span class="string">@"%@\n%@"</span>, response, _textView.text];</div><div class="line">&#125;</div><div class="line"></div><div class="line">- (<span class="keyword">void</span>)didReceiveMemoryWarning &#123;</div><div class="line">    [<span class="keyword">super</span> didReceiveMemoryWarning];</div><div class="line">    <span class="comment">// Dispose of any resources that can be recreated.</span></div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">@end</span></div></pre></td></tr></table></figure>
<p>“Product &gt; Run”运行项目。 UI 上”Get Hello Djinni!”的按钮，每点击下就会添加条从 C++ 返回的信息。</p>
<img src="/2016/05/06/using-djinni/ios_pro_result.png" width="300">
<h3 id="Android-工程"><a href="#Android-工程" class="headerlink" title="Android 工程"></a>Android 工程</h3><p>Android 工程介绍了两种方式，来整合 NDK Library ：</p>
<ul>
<li>一是，使用 GYP 生成的 Android Makefile ， Gradle 配置 ndk-build 进行编译。</li>
<li>二是，使用 Experimental Plugin ，直接配置成支持 NDK 的工程。</li>
</ul>
<h4 id="使用-GypMakefile"><a href="#使用-GypMakefile" class="headerlink" title="使用 GypMakefile"></a>使用 GypMakefile</h4><p>GYP 生成 Android Makefile ，使用之前写好的<code>project/Makefile</code>：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> project/</div><div class="line">$ make android_pro</div></pre></td></tr></table></figure>
<p><code>GypAndroid.mk</code>会生成到父级<code>hellodjinni</code>目录。</p>
<p>如果还没准备好 Studio 工程，不会继续生成 APK ，会报“找不到<code>android/HelloDjinni/</code>”。</p>
<p>现在，打开 Android Studio，选择”Start a new Android Studio Project”。</p>
<p>“New”页，”Project Location”存到<code>project/android/HelloDjinni</code>，如下：</p>
<img src="/2016/05/06/using-djinni/android_pro_new.png" alt="android_pro_new.png" title="">
<p>之后，”Target”页选”Phone and Tablet”，”Add”页选”Empty Activity”，最终完成新建。</p>
<p>于”File &gt; Project Structure &gt; SDK Location &gt; Android NDK Location”，设置 NDK 路径：</p>
<img src="/2016/05/06/using-djinni/android_pro_sdk.png" alt="android_pro_sdk.png" title="">
<p>接下来，独立建一个 app-core Library 模块来引用 C++ 代码。”File &gt; New Module”，选”Android Library”：</p>
<img src="/2016/05/06/using-djinni/android_pro_new_lib.png" alt="android_pro_new_lib.png" title="">
<p>然后，修改此 app-core 的<code>build.gradle</code>，添加引用及 NDK 编译。变更如下：</p>
<figure class="highlight gradle"><figcaption><span>project/android/HelloDjinni/app-core/build.gradle</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app-core/build.gradle" target="_blank" rel="external">build.gradle</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line">apply plugin: <span class="string">'com.android.library'</span></div><div class="line"></div><div class="line">android &#123;</div><div class="line">    ...</div><div class="line">    <span class="keyword">sourceSets</span> &#123;</div><div class="line">        main &#123;</div><div class="line">            java.srcDirs += [<span class="string">'../../../../generated-src/java'</span>]</div><div class="line">            jni.srcDirs = []</div><div class="line">            jniLibs.srcDirs = [<span class="string">'libs'</span>]</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">dependencies</span> &#123;</div><div class="line">    ...</div><div class="line">    <span class="comment">//compile 'com.android.support:appcompat-v7:23.3.0'</span></div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">task</span> ndkBuild(type: Exec) &#123;</div><div class="line">    <span class="keyword">def</span> ndkDir = plugins.getPlugin(<span class="string">'com.android.library'</span>).sdkHandler.ndkFolder</div><div class="line">    <span class="keyword">if</span> (ndkDir == <span class="keyword">null</span>) &#123;</div><div class="line">        <span class="keyword">def</span> gradle_project_root = <span class="keyword">project</span>.rootProject.rootDir</div><div class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> GradleException(<span class="string">"NDK is not configured. Make sure there is a local.properties "</span> +</div><div class="line">                <span class="string">"file with an ndk.dir entry in the directory $&#123;gradle_project_root&#125;."</span>)</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">def</span> ndkBuildExecutable = <span class="keyword">new</span> <span class="keyword">File</span>(ndkDir, <span class="string">'ndk-build'</span>)</div><div class="line">    <span class="keyword">if</span> (!ndkBuildExecutable.exists()) &#123;</div><div class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> GradleException(<span class="string">"Could not find ndk-build. The configured NDK directory $&#123;ndkDir&#125; may not be correct."</span>)</div><div class="line">    &#125;</div><div class="line">    environment(<span class="string">"NDK_PROJECT_PATH"</span>, projectDir)</div><div class="line">    environment(<span class="string">"GYP_CONFIGURATION"</span>, <span class="string">"Release"</span>)</div><div class="line">    commandLine ndkBuildExecutable</div><div class="line">&#125;</div><div class="line"></div><div class="line">tasks.withType(JavaCompile) &#123;</div><div class="line">    compileTask -&gt; compileTask.dependsOn ndkBuild</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>项目导航栏切到 Project 视图，在 app-core 下新建<code>jni</code>目录，创建 NDK 的工程文件。</p>
<figure class="highlight makefile"><figcaption><span>project/android/HelloDjinni/app-core/jni/Android.mk</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app-core/jni/Android.mk" target="_blank" rel="external">Android.mk</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># always force this build to re-run its dependencies</span></div><div class="line">FORCE_GYP := <span class="variable">$(shell make -C ../../../../ GypAndroid.mk)</span></div><div class="line">include ../../../../GypAndroid.mk</div></pre></td></tr></table></figure>
<figure class="highlight makefile"><figcaption><span>project/android/HelloDjinni/app-core/jni/Application.mk</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app-core/jni/Application.mk" target="_blank" rel="external">Application.mk</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># Android makefile for libhellodjinni shared lib</span></div><div class="line"></div><div class="line"><span class="comment"># Application.mk: http://developer.android.com/ndk/guides/application_mk.html</span></div><div class="line"></div><div class="line"><span class="comment"># APP_ABI := all</span></div><div class="line"><span class="comment"># skipping mips / mips64</span></div><div class="line">APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64</div><div class="line">APP_OPTIM := release</div><div class="line">APP_PLATFORM := android-14</div><div class="line"><span class="comment"># GCC 4.9 Toolchain - requires NDK r10</span></div><div class="line">NDK_TOOLCHAIN_VERSION = 4.9</div><div class="line"><span class="comment"># GNU libc++ is the only Android STL which supports C++11 features</span></div><div class="line">APP_CFLAGS += -Wall</div><div class="line">APP_CPPFLAGS += -std=c++11 -frtti -fexceptions</div><div class="line">APP_STL := gnustl_static</div><div class="line">APP_BUILD_SCRIPT := jni/Android.mk</div><div class="line">APP_MODULES := libhellodjinni_jni</div></pre></td></tr></table></figure>
<p>这样，独立的 app-core Library 就👌了。</p>
<p>回到 app ，修改其<code>build.gradle</code>，以依赖 app-core 。变更如下：</p>
<figure class="highlight gradle"><figcaption><span>project/android/HelloDjinni/app/build.gradle</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app/build.gradle" target="_blank" rel="external">build.gradle</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">dependencies</span> &#123;</div><div class="line">    ...</div><div class="line">    <span class="keyword">compile</span> <span class="keyword">project</span>(<span class="string">':app-core'</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>新建<code>MyApplication.java</code>，作为自定义 Application。并设置到<code>AndroidManifest.xml</code>内”application”的”name”字段。</p>
<figure class="highlight java"><figcaption><span>project/android/HelloDjinni/app/src/.../MyApplication.java</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app/src/main/java/cc/eevee/hellodjinni/MyApplication.java" target="_blank" rel="external">MyApplication.java</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> cc.eevee.hellodjinni;</div><div class="line"></div><div class="line"><span class="keyword">import</span> android.app.Application;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyApplication</span> <span class="keyword">extends</span> <span class="title">Application</span> </span>&#123;</div><div class="line"></div><div class="line">    <span class="keyword">static</span> &#123;</div><div class="line">        <span class="keyword">try</span> &#123;</div><div class="line">            System.loadLibrary(<span class="string">"hellodjinni_jni"</span>);</div><div class="line">        &#125; <span class="keyword">catch</span> (UnsatisfiedLinkError e) &#123;</div><div class="line">            System.err.println(<span class="string">"Native code library failed to load.\n"</span> + e);</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>.onCreate();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>最终，项目导航 Android 和 Project 视图类似下面这样：</p>
<img src="/2016/05/06/using-djinni/android_pro_nav.png" alt="android_pro_nav.png" title="">
<p>接着，修改 app UI，<code>MainActivity.java</code>及其布局<code>activity_main.xml</code>：</p>
<figure class="highlight java"><figcaption><span>project/android/HelloDjinni/app/src/.../MainActivity.java</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app/src/main/java/cc/eevee/hellodjinni/MainActivity.java" target="_blank" rel="external">MainActivity.java</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> cc.eevee.hellodjinni;</div><div class="line"></div><div class="line"><span class="keyword">import</span> android.support.v7.app.AppCompatActivity;</div><div class="line"><span class="keyword">import</span> android.os.Bundle;</div><div class="line"><span class="keyword">import</span> android.view.View;</div><div class="line"><span class="keyword">import</span> android.widget.ScrollView;</div><div class="line"><span class="keyword">import</span> android.widget.TextView;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>&#123;</div><div class="line"></div><div class="line">    <span class="keyword">private</span> TextView mTextView;</div><div class="line">    <span class="keyword">private</span> ScrollView mScrollView;</div><div class="line"></div><div class="line">    <span class="keyword">private</span> HelloDjinni mHelloDjinniInterface = HelloDjinni.create();</div><div class="line"></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState);</div><div class="line">        setContentView(R.layout.activity_main);</div><div class="line">        mTextView = (TextView) findViewById(R.id.textView);</div><div class="line">        mScrollView = (ScrollView) findViewById(R.id.scrollView);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onButtonClick</span><span class="params">(View view)</span> </span>&#123;</div><div class="line">        mTextView.append(mHelloDjinniInterface.getHelloDjinni() + <span class="string">"\n"</span>);</div><div class="line">        mScrollView.fullScroll(ScrollView.FOCUS_DOWN);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight xml"><figcaption><span>project/android/HelloDjinni/app/src/.../activity_main.xml</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni/app/src/main/res/layout/activity_main.xml" target="_blank" rel="external">activity_main.xml</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line">&lt;?xml version="1.0" encoding="utf-8"?&gt;</div><div class="line"><span class="tag">&lt;<span class="name">LinearLayout</span></span></div><div class="line">    <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></div><div class="line">    <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></div><div class="line">    <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">    <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></div><div class="line">    <span class="attr">android:orientation</span>=<span class="string">"vertical"</span></div><div class="line">    <span class="attr">android:paddingBottom</span>=<span class="string">"@dimen/activity_vertical_margin"</span></div><div class="line">    <span class="attr">android:paddingLeft</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></div><div class="line">    <span class="attr">android:paddingRight</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></div><div class="line">    <span class="attr">android:paddingTop</span>=<span class="string">"@dimen/activity_vertical_margin"</span></div><div class="line">    <span class="attr">tools:context</span>=<span class="string">"cc.eevee.hellodjinni.MainActivity"</span>&gt;</div><div class="line"></div><div class="line">    <span class="tag">&lt;<span class="name">Button</span></span></div><div class="line">        <span class="attr">android:id</span>=<span class="string">"@+id/button"</span></div><div class="line">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">        <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line">        <span class="attr">android:text</span>=<span class="string">"Get Hello Djinni!"</span></div><div class="line">        <span class="attr">android:gravity</span>=<span class="string">"center"</span></div><div class="line">        <span class="attr">android:onClick</span>=<span class="string">"onButtonClick"</span>/&gt;</div><div class="line"></div><div class="line">    <span class="tag">&lt;<span class="name">ScrollView</span></span></div><div class="line">        <span class="attr">android:id</span>=<span class="string">"@+id/scrollView"</span></div><div class="line">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">        <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span>&gt;</div><div class="line"></div><div class="line">        <span class="tag">&lt;<span class="name">TextView</span></span></div><div class="line">            <span class="attr">android:id</span>=<span class="string">"@+id/textView"</span></div><div class="line">            <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">            <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span>/&gt;</div><div class="line">    <span class="tag">&lt;/<span class="name">ScrollView</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">LinearLayout</span>&gt;</span></div></pre></td></tr></table></figure>
<p>“Run &gt; Run ‘app’”运行项目。 UI 上”Get Hello Djinni!”的按钮，每点击下就会添加条从 C++ 返回的信息。</p>
<img src="/2016/05/06/using-djinni/android_pro_result.png" width="300">
<h4 id="使用新试验性插件"><a href="#使用新试验性插件" class="headerlink" title="使用新试验性插件"></a>使用新试验性插件</h4><p>Android Studio 1.3 版本开始支持 NDK，需要使用 Experimental Plugin 。这里为当前最新的 0.7.0 版本。</p>
<p>同样，打开 Android Studio，选择”Start a new Android Studio Project”，新建一个”HelloDjinni2”工程。</p>
<img src="/2016/05/06/using-djinni/android_pro2_new.png" alt="android_pro2_new.png" title="">
<p>之后，”Target”页选”Phone and Tablet”，”Add”页选”Empty Activity”，最终完成新建。</p>
<p>于”File &gt; Project Structure &gt; SDK Location &gt; Android NDK Location”，设置 NDK 路径。</p>
<p>接下来，修改成 Experimental Plugin 。先是工程配置：</p>
<figure class="highlight gradle"><figcaption><span>project/android/HelloDjinni2/build.gradle</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/build.gradle" target="_blank" rel="external">build.gradle</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// Top-level build file where you can add configuration options common to all sub-projects/modules.</span></div><div class="line"></div><div class="line"><span class="keyword">buildscript</span> &#123;</div><div class="line">    <span class="keyword">repositories</span> &#123;</div><div class="line">        jcenter()</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">dependencies</span> &#123;</div><div class="line">        <span class="keyword">classpath</span> <span class="string">'com.android.tools.build:gradle-experimental:0.7.0'</span></div><div class="line"></div><div class="line">        <span class="comment">// <span class="doctag">NOTE:</span> Do not place your application dependencies here; they belong</span></div><div class="line">        <span class="comment">// in the individual module build.gradle files</span></div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">allprojects</span> &#123;</div><div class="line">    <span class="keyword">repositories</span> &#123;</div><div class="line">        jcenter()</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">task</span> clean(type: <span class="keyword">Delete</span>) &#123;</div><div class="line">    <span class="keyword">delete</span> rootProject.buildDir</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>接着是 app 模块配置：</p>
<figure class="highlight gradle"><figcaption><span>project/android/HelloDjinni2/app/build.gradle</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/app/build.gradle" target="_blank" rel="external">build.gradle</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div></pre></td><td class="code"><pre><div class="line">apply plugin: <span class="string">'com.android.model.application'</span></div><div class="line"></div><div class="line">model &#123;</div><div class="line">    android &#123;</div><div class="line">        compileSdkVersion = <span class="number">23</span></div><div class="line">        buildToolsVersion = <span class="string">'23.0.3'</span></div><div class="line"></div><div class="line">        defaultConfig &#123;</div><div class="line">            applicationId = <span class="string">'cc.eevee.hellodjinni2'</span></div><div class="line">            minSdkVersion.apiLevel    = <span class="number">14</span></div><div class="line">            targetSdkVersion.apiLevel = <span class="number">23</span></div><div class="line">            versionCode = <span class="number">1</span></div><div class="line">            versionName = <span class="string">'1.0'</span></div><div class="line">        &#125;</div><div class="line">        buildTypes &#123;</div><div class="line">            release &#123;</div><div class="line">                minifyEnabled = <span class="keyword">false</span></div><div class="line">                proguardFiles.add(<span class="keyword">file</span>(<span class="string">'proguard-rules.pro'</span>))</div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">dependencies</span> &#123;</div><div class="line">    <span class="keyword">compile</span> <span class="keyword">fileTree</span>(dir: <span class="string">'libs'</span>, <span class="keyword">include</span>: [<span class="string">'*.jar'</span>])</div><div class="line">    testCompile <span class="string">'junit:junit:4.12'</span></div><div class="line">    <span class="keyword">compile</span> <span class="string">'com.android.support:appcompat-v7:23.3.0'</span></div><div class="line">    <span class="comment">//compile project(':app-core')</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>这样， Experimental Plugin 就修改完成了。</p>
<p>接下来，仍旧独立建一个 app-core Library 模块来引用 C++ 代码。”File &gt; New Module”，选”Android Library”：</p>
<img src="/2016/05/06/using-djinni/android_pro2_new_lib.png" alt="android_pro2_new_lib.png" title="">
<p>然后，修改此 app-core 的<code>build.gradle</code>，支持 Experimental Plugin 并配置 NDK 。如下：</p>
<figure class="highlight gradle"><figcaption><span>project/android/HelloDjinni2/app-core/build.gradle</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/app-core/build.gradle" target="_blank" rel="external">build.gradle</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div></pre></td><td class="code"><pre><div class="line">apply plugin: <span class="string">'com.android.model.library'</span></div><div class="line"></div><div class="line">model &#123;</div><div class="line">    android &#123;</div><div class="line">        compileSdkVersion = <span class="number">23</span></div><div class="line">        buildToolsVersion = <span class="string">'23.0.3'</span></div><div class="line"></div><div class="line">        defaultConfig &#123;</div><div class="line">            minSdkVersion.apiLevel    = <span class="number">14</span></div><div class="line">            targetSdkVersion.apiLevel = <span class="number">23</span></div><div class="line">        &#125;</div><div class="line">        ndk &#123;</div><div class="line">            moduleName = <span class="string">'hellodjinni'</span></div><div class="line">            platformVersion = <span class="number">14</span></div><div class="line">            toolchain = <span class="string">'gcc'</span></div><div class="line">            toolchainVersion = <span class="string">'4.9'</span></div><div class="line">            stl = <span class="string">'gnustl_shared'</span></div><div class="line">            CFlags.addAll([<span class="string">'-Wall'</span>, <span class="string">'-Werror'</span>])</div><div class="line">            cppFlags.addAll([<span class="string">'-std=c++11'</span>, <span class="string">'-fexceptions'</span>, <span class="string">'-frtti'</span>])</div><div class="line">            cppFlags.addAll([</div><div class="line">                    <span class="string">"-I$&#123;file('../../../deps/djinni/support-lib')&#125;"</span>.toString(),</div><div class="line">                    <span class="string">"-I$&#123;file('../../../deps/djinni/support-lib/jni')&#125;"</span>.toString(),</div><div class="line">                    <span class="string">"-I$&#123;file('../../../../generated-src/cpp')&#125;"</span>.toString(),</div><div class="line">                    <span class="string">"-I$&#123;file('../../../../generated-src/jni')&#125;"</span>.toString(),</div><div class="line">            ])</div><div class="line">            ldLibs.addAll([<span class="string">'log'</span>])</div><div class="line">            abiFilters.addAll([<span class="string">'armeabi'</span>, <span class="string">'armeabi-v7a'</span>, <span class="string">'arm64-v8a'</span>, <span class="string">'x86'</span>, <span class="string">'x86_64'</span>])</div><div class="line">        &#125;</div><div class="line">        sources &#123;</div><div class="line">            <span class="comment">//noinspection GroovyAssignabilityCheck</span></div><div class="line">            main &#123;</div><div class="line">                jni &#123;</div><div class="line">                    <span class="keyword">source</span> &#123;</div><div class="line">                        srcDirs += [</div><div class="line">                            <span class="string">'../../../deps/djinni/support-lib/jni'</span>,</div><div class="line">                            <span class="string">'../../../../generated-src/cpp'</span>,</div><div class="line">                            <span class="string">'../../../../generated-src/jni'</span>,</div><div class="line">                            <span class="string">'../../../../src/cpp'</span>,</div><div class="line">                        ]</div><div class="line">                    &#125;</div><div class="line">                &#125;</div><div class="line">                java &#123;</div><div class="line">                    <span class="keyword">source</span> &#123;</div><div class="line">                        srcDirs += [</div><div class="line">                            <span class="string">'../../../../generated-src/java'</span>,</div><div class="line">                        ]</div><div class="line">                    &#125;</div><div class="line">                &#125;</div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">        buildTypes &#123;</div><div class="line">            release &#123;</div><div class="line">                minifyEnabled = <span class="keyword">false</span></div><div class="line">                proguardFiles.add(<span class="keyword">file</span>(<span class="string">'proguard-rules.pro'</span>))</div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">dependencies</span> &#123;</div><div class="line">    <span class="keyword">compile</span> <span class="keyword">fileTree</span>(dir: <span class="string">'libs'</span>, <span class="keyword">include</span>: [<span class="string">'*.jar'</span>])</div><div class="line">    testCompile <span class="string">'junit:junit:4.12'</span></div><div class="line">    <span class="comment">//compile 'com.android.support:appcompat-v7:23.3.0'</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>这样之后，可以在 app-core 下看得<code>jni</code>目录，包括了所有 C++ 代码。</p>
<p>回到 app ，修改其<code>build.gradle</code>，以依赖 app-core 。变更如下：</p>
<figure class="highlight gradle"><figcaption><span>project/android/HelloDjinni2/app/build.gradle</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/app/build.gradle" target="_blank" rel="external">build.gradle</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">dependencies</span> &#123;</div><div class="line">    ...</div><div class="line">    <span class="keyword">compile</span> <span class="keyword">project</span>(<span class="string">':app-core'</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>新建<code>MyApplication.java</code>，作为自定义 Application。并设置到<code>AndroidManifest.xml</code>内”application”的”name”字段。</p>
<figure class="highlight java"><figcaption><span>project/android/HelloDjinni2/app/src/.../MyApplication.java</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/app/src/main/java/cc/eevee/hellodjinni2/MyApplication.java" target="_blank" rel="external">MyApplication.java</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> cc.eevee.hellodjinni2;</div><div class="line"></div><div class="line"><span class="keyword">import</span> android.app.Application;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyApplication</span> <span class="keyword">extends</span> <span class="title">Application</span> </span>&#123;</div><div class="line"></div><div class="line">    <span class="keyword">static</span> &#123;</div><div class="line">        <span class="keyword">try</span> &#123;</div><div class="line">            System.loadLibrary(<span class="string">"gnustl_shared"</span>);</div><div class="line">            System.loadLibrary(<span class="string">"hellodjinni"</span>);</div><div class="line">        &#125; <span class="keyword">catch</span> (UnsatisfiedLinkError e) &#123;</div><div class="line">            System.err.println(<span class="string">"Native code library failed to load.\n"</span> + e);</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>.onCreate();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>最终，项目导航 Android 和 Project 视图类似下面这样：</p>
<img src="/2016/05/06/using-djinni/android_pro2_nav.png" alt="android_pro2_nav.png" title="">
<p>接着，修改 app UI，<code>MainActivity.java</code>及其布局<code>activity_main.xml</code>：</p>
<figure class="highlight java"><figcaption><span>project/android/HelloDjinni2/app/src/.../MainActivity.java</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/app/src/main/java/cc/eevee/hellodjinni2/MainActivity.java" target="_blank" rel="external">MainActivity.java</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> cc.eevee.hellodjinni2;</div><div class="line"></div><div class="line"><span class="keyword">import</span> android.support.v7.app.AppCompatActivity;</div><div class="line"><span class="keyword">import</span> android.os.Bundle;</div><div class="line"><span class="keyword">import</span> android.view.View;</div><div class="line"><span class="keyword">import</span> android.widget.ScrollView;</div><div class="line"><span class="keyword">import</span> android.widget.TextView;</div><div class="line"></div><div class="line"><span class="keyword">import</span> cc.eevee.hellodjinni.HelloDjinni;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>&#123;</div><div class="line"></div><div class="line">    <span class="keyword">private</span> TextView mTextView;</div><div class="line">    <span class="keyword">private</span> ScrollView mScrollView;</div><div class="line"></div><div class="line">    <span class="keyword">private</span> HelloDjinni mHelloDjinniInterface = HelloDjinni.create();</div><div class="line"></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState);</div><div class="line">        setContentView(R.layout.activity_main);</div><div class="line">        mTextView = (TextView) findViewById(R.id.textView);</div><div class="line">        mScrollView = (ScrollView) findViewById(R.id.scrollView);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onButtonClick</span><span class="params">(View view)</span> </span>&#123;</div><div class="line">        mTextView.append(mHelloDjinniInterface.getHelloDjinni() + <span class="string">"\n"</span>);</div><div class="line">        mScrollView.fullScroll(ScrollView.FOCUS_DOWN);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight xml"><figcaption><span>project/android/HelloDjinni2/app/src/.../activity_main.xml</span><a href="https://github.com/joinAero/XCalculator/tree/master/sample/hellodjinni/project/android/HelloDjinni2/app/src/main/res/layout/activity_main.xml" target="_blank" rel="external">activity_main.xml</a></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line">&lt;?xml version="1.0" encoding="utf-8"?&gt;</div><div class="line"><span class="tag">&lt;<span class="name">LinearLayout</span></span></div><div class="line">    <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></div><div class="line">    <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></div><div class="line">    <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">    <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></div><div class="line">    <span class="attr">android:orientation</span>=<span class="string">"vertical"</span></div><div class="line">    <span class="attr">android:paddingBottom</span>=<span class="string">"@dimen/activity_vertical_margin"</span></div><div class="line">    <span class="attr">android:paddingLeft</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></div><div class="line">    <span class="attr">android:paddingRight</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></div><div class="line">    <span class="attr">android:paddingTop</span>=<span class="string">"@dimen/activity_vertical_margin"</span></div><div class="line">    <span class="attr">tools:context</span>=<span class="string">"cc.eevee.hellodjinni2.MainActivity"</span>&gt;</div><div class="line"></div><div class="line">    <span class="tag">&lt;<span class="name">Button</span></span></div><div class="line">        <span class="attr">android:id</span>=<span class="string">"@+id/button"</span></div><div class="line">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">        <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line">        <span class="attr">android:text</span>=<span class="string">"Get Hello Djinni!"</span></div><div class="line">        <span class="attr">android:gravity</span>=<span class="string">"center"</span></div><div class="line">        <span class="attr">android:onClick</span>=<span class="string">"onButtonClick"</span>/&gt;</div><div class="line"></div><div class="line">    <span class="tag">&lt;<span class="name">ScrollView</span></span></div><div class="line">        <span class="attr">android:id</span>=<span class="string">"@+id/scrollView"</span></div><div class="line">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">        <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span>&gt;</div><div class="line"></div><div class="line">        <span class="tag">&lt;<span class="name">TextView</span></span></div><div class="line">            <span class="attr">android:id</span>=<span class="string">"@+id/textView"</span></div><div class="line">            <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></div><div class="line">            <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span>/&gt;</div><div class="line">    <span class="tag">&lt;/<span class="name">ScrollView</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">LinearLayout</span>&gt;</span></div></pre></td></tr></table></figure>
<p>“Run &gt; Run ‘app’”运行项目。 UI 上”Get Hello Djinni!”的按钮，每点击下就会添加条从 C++ 返回的信息。</p>
<img src="/2016/05/06/using-djinni/android_pro2_result.png" width="300">
<h4 id="NDK-参考"><a href="#NDK-参考" class="headerlink" title="NDK 参考"></a>NDK 参考</h4><ul>
<li><a href="http://developer.android.com/ndk/guides/index.html" target="_blank" rel="external">NDK Guides</a></li>
<li><a href="http://tools.android.com/tech-docs/android-ndk-preview" target="_blank" rel="external">Android NDK Preview</a></li>
<li><a href="http://tools.android.com/tech-docs/new-build-system/gradle-experimental" target="_blank" rel="external">Experimental Plugin User Guide</a></li>
<li><a href="http://stackoverflow.com/questions/31979965/after-updating-android-studio-to-version-1-3-0-i-am-getting-ndk-integration-is" target="_blank" rel="external">Error: NDK integration is deprecated in the current plugin</a></li>
</ul>
<h2 id="结语：开始使用-Djinni-吧"><a href="#结语：开始使用-Djinni-吧" class="headerlink" title="结语：开始使用 Djinni 吧"></a>结语：开始使用 Djinni 吧</h2><h2 id="附：源码"><a href="#附：源码" class="headerlink" title="附：源码"></a>附：源码</h2><p>Hello Djinni 的源码，这样得到：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ git <span class="built_in">clone</span> https://github.com/joinAero/XCalculator.git</div><div class="line">$ <span class="built_in">cd</span> sample/hellodjinni/</div></pre></td></tr></table></figure>
<p>修改<code>local.properties</code>设好环境。执行<code>make</code>编译，<code>make clean</code>清理。</p>
<p><strong>文件结构：</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">hellodjinni/</div><div class="line">├─project/</div><div class="line">│  ├─android/</div><div class="line">│  │  ├─HelloDjinni/                # Android Project with GYP &amp; ndk-build</div><div class="line">│  │  └─HelloDjinni2/               # Android Project with Experimental Plugin</div><div class="line">│  ├─cpp/</div><div class="line">│  │  └─HelloDjinni/                # Cpp Test Project</div><div class="line">│  └─ios/</div><div class="line">│      ├─HelloDjinni/</div><div class="line">│      └─HelloDjinni.xcworkspace/   # iOS Project Workspace</div><div class="line">├─src/</div><div class="line">│  └─cpp/                           # Cpp Interface Impls</div><div class="line">├─tools/                            # Helper Scripts</div><div class="line">└─local.properties                  # Local Properties</div></pre></td></tr></table></figure>
<h2 id="附：运行环境"><a href="#附：运行环境" class="headerlink" title="附：运行环境"></a>附：运行环境</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># OS</span></div><div class="line">ProductName: Mac OS X ProductVersion: 10.11.4 BuildVersion: 15E65</div><div class="line"></div><div class="line"><span class="comment"># XCode</span></div><div class="line">Xcode 7.3.1 Build version 7D1014</div><div class="line"></div><div class="line"><span class="comment"># XCode 命令行工具</span></div><div class="line"><span class="comment"># xcode-select --install</span></div><div class="line">xcode-select version 2343.</div><div class="line"></div><div class="line"><span class="comment"># Java</span></div><div class="line">java version <span class="string">"1.8.0_25"</span></div><div class="line">Java(TM) SE Runtime Environment (build 1.8.0_25-b17)</div><div class="line">Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)</div><div class="line"></div><div class="line"><span class="comment"># Android Studio</span></div><div class="line"><span class="comment"># Android Studio &gt; About Android Studio</span></div><div class="line"><span class="comment"># Android Studio &gt; Appearance &amp; Behavior &gt; System Settings &gt; Updates</span></div><div class="line">Android Studio 2.1</div><div class="line">Build <span class="comment">#AI-143.2790544</span></div><div class="line"></div><div class="line"><span class="comment"># Android NDK</span></div><div class="line">GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the <span class="built_in">source</span> <span class="keyword">for</span> copying conditions. There is NO warranty; not even <span class="keyword">for</span> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built <span class="keyword">for</span> i386-apple-darwin11.3.0</div></pre></td></tr></table></figure>
<p>如果未添加过 Android 环境变量，请于 ~/.bash_profile 文件内设置：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">export</span> ANDROID_HOME=<span class="variable">$HOME</span>/Develop/android-sdk</div><div class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:<span class="variable">$ANDROID_HOME</span>/tools:<span class="variable">$ANDROID_HOME</span>/platform-tools</div><div class="line"></div><div class="line"><span class="built_in">export</span> ANDROID_NDK_HOME=<span class="variable">$HOME</span>/Develop/android-ndk</div><div class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:<span class="variable">$ANDROID_NDK_HOME</span></div></pre></td></tr></table></figure>
<p>终端运行如下命令可立即生效：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">source</span> ~/.bash_profile</div></pre></td></tr></table></figure>
<p>验证 SDK 与 NDK 命令行工具可用：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">which</span> android</div><div class="line"></div><div class="line">$ <span class="built_in">which</span> ndk-build</div></pre></td></tr></table></figure>
<p>验证 XCode 命令行工具可用：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">which</span> xcrun</div><div class="line"></div><div class="line">$ <span class="built_in">which</span> xcodebuild</div></pre></td></tr></table></figure>
<h2 id="附：参考内容"><a href="#附：参考内容" class="headerlink" title="附：参考内容"></a>附：参考内容</h2><ul>
<li><a href="http://mobilecpptutorials.com/your-first-cross-platform-djinni-app-part-1-cplusplus/" target="_blank" rel="external">Your First Cross-Platform Djinni App</a></li>
<li><a href="http://www.infoq.com/cn/news/2014/06/dropbox-cpp-crossplatform-mobile/" target="_blank" rel="external">iOS和Android的C++跨平台开发 | Dropbox</a></li>
</ul>
<!--
Projects:

* [djinni | dropbox](https://github.com/dropbox/djinni)
* [android-ndk | googlesamples](https://github.com/googlesamples/android-ndk.git)

References:

* [Cpp Reference](http://en.cppreference.com)
* [NDK API Reference](http://developer.android.com/ndk/reference/index.html)
* [iOS Developer Library](https://developer.apple.com/library/ios)
* [Mac Developer Library](https://developer.apple.com/library/mac)

Extra Articles:

* [From C++ to Objective-C](http://pierre.chachatelier.fr/programmation/fichiers/cpp-objc-2_1-en.pdf)

Extra Tools:

* [sbt](http://www.scala-sbt.org/index.html): `brew install sbt`
* [sbt下载慢？](http://www.zhihu.com/question/31158252)
-->
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;a href=&quot;https://github.com/dropbox/djinni&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Djinni&lt;/a&gt; 是一个用来生成跨语言的类型声明和接口绑定的工具，主要用于 C++ 和 Java 以及 Objective-C 间的互通。&lt;/p&gt;
&lt;p&gt;此文，将介绍如何使用 &lt;a href=&quot;https://github.com/dropbox/djinni&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Djinni&lt;/a&gt; 开发 Android, iOS 的共享库。这会带来几个好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用了接口描述文件。声明清晰、修改简易，并保证了跨平台接口的一致性。&lt;/li&gt;
&lt;li&gt;自动生成接口绑定代码。免去了绑定 C++ 和 Java (JNI) 及 Objective-C (Objective-C++) 的麻烦。&lt;/li&gt;
&lt;/ul&gt;

&lt;style type=&quot;text/css&quot;&gt;
.post-body .fancybox img { margin: 0 auto 25px; }
&lt;/style&gt;

&lt;h2 id=&quot;初见：Djinni-及其样例&quot;&gt;&lt;a href=&quot;#初见：Djinni-及其样例&quot; class=&quot;headerlink&quot; title=&quot;初见：Djinni 及其样例&quot;&gt;&lt;/a&gt;初见：Djinni 及其样例&lt;/h2&gt;&lt;h3 id=&quot;下载-Djinni&quot;&gt;&lt;a href=&quot;#下载-Djinni&quot; class=&quot;headerlink&quot; title=&quot;下载 Djinni&quot;&gt;&lt;/a&gt;下载 Djinni&lt;/h3&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/dropbox/djinni.git&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&quot;编译-Djinni&quot;&gt;&lt;a href=&quot;#编译-Djinni&quot; class=&quot;headerlink&quot; title=&quot;编译 Djinni&quot;&gt;&lt;/a&gt;编译 Djinni&lt;/h3&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;$ &lt;span class=&quot;built_in&quot;&gt;cd&lt;/span&gt; [djinni_root]/&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;$ src/build&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;于&lt;code&gt;[djinni_root]/src/support/sbt.resolvers.properties&lt;/code&gt;内可添加镜像源。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.zhihu.com/question/31158252&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;sbt下载慢？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;使用-Djinni&quot;&gt;&lt;a href=&quot;#使用-Djinni&quot; class=&quot;headerlink&quot; title=&quot;使用 Djinni&quot;&gt;&lt;/a&gt;使用 Djinni&lt;/h3&gt;
    
    </summary>
    
      <category term="Tech" scheme="http://eevee.cc/categories/Tech/"/>
    
    
      <category term="Djinni" scheme="http://eevee.cc/tags/Djinni/"/>
    
      <category term="Cpp" scheme="http://eevee.cc/tags/Cpp/"/>
    
      <category term="Android" scheme="http://eevee.cc/tags/Android/"/>
    
      <category term="iOS" scheme="http://eevee.cc/tags/iOS/"/>
    
  </entry>
  
</feed>
