title: How to build in a separate directory with autotool
body: <p>I have a working directory as below:</p>
  
  <p>./<br>
  |----HelloWorld/<br>
  |----|----main.cpp<br>
  |----|----Makefile.am<br>
  |----Pet/<br>
  |----|----Pet.h<br>
  |----|----Pet.cpp<br>
  |----build/<br>
  |----configure.ac<br>
  |----Makefile.am  </p>
  
  <p>I would like to use the autotool to construct makefile and then build the project in the build directory.</p>
  
  <p>The <strong>./configure.ac</strong> is</p>
  
  <pre><code>#                                               -*- Autoconf -*-
  # Process this file with autoconf to produce a configure script.
  
  AC_PREREQ([2.69])
  AC_INIT([Hello], [1.0], [qub@oregonstate.edu])
  AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
  AC_CONFIG_SRCDIR([HelloWorld/main.cpp])
  AC_CONFIG_HEADERS([config.h])
  
  # Checks for programs.
  AC_PROG_CXX
  AC_PROG_CC
  
  AC_CONFIG_FILES([Makefile])
  AC_OUTPUT
  
  </code></pre>
  
  <p>The <strong>./Makefile.am</strong> is</p>
  
  <pre><code>include HelloWorld/Makefile.am
  </code></pre>
  
  <p>Note that I'm using the include to make sure the exe locates at the directory where the make command runs.</p>
  
  <p>The <strong>./HelloWorld/Makefile.am</strong> is</p>
  
  <pre><code>AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C%
  #VPATH = ./HelloWorld ./Pet
  
  bin_PROGRAMS=hello
  
  hello_SOURCES=%D%/../Pet/Pet.h 
  hello_SOURCES+=%D%/../Pet/Pet.cpp 
  hello_SOURCES+=%D%/main.cpp
  </code></pre>
  
  <p>In case some people would like to try on their own computer, I attach other source codes here:
  <strong>main.cpp</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;vector&gt;
  #include "Pet.h"
  
  int main() {
  
      printf("Hello World\n");
  
      std::vector&lt;Pet*&gt; all_pets;
  
      Pet *dog = new Pet(string("Apple"));
      all_pets.push_back(dog);
  
      Pet *cat = new Pet(string("Pear"));
      all_pets.push_back(cat);
  
      for (int i = 0; i &lt; all_pets.size(); i++) {
          all_pets[i]-&gt;showName();
      }
  
      return 0;
  }
  
  </code></pre>
  
  <pre><code>**Pet.h**
  </code></pre>
  
  <pre><code>#pragma once
  #include &lt;string&gt;
  using namespace std;
  class Pet
  {
      public:
      Pet(string name);
      ~Pet();
  
      void showName();
      void showIndex();
  
      string _name;
      int _index;
  };
  
  </code></pre>
  
  <p><strong>Pet.cpp</strong></p>
  
  <pre><code>#include "Pet.h"
  
  Pet::Pet(string name)
  {
      _name = name;
      srand(2345);
      _index = (rand() % 100);
  }
  
  
  Pet::~Pet()
  {
  }
  
  void Pet::showIndex()
  {
      printf("Index is %d\n", _index);
  }
  
  void Pet::showName()
  {
      printf("Name is %s\n", _name.c_str());
  }
  
  </code></pre>
  
  <p><strong>Problem Statement</strong>  </p>
  
  <ol>
  <li>Can successfully create makefile by run</li>
  </ol>
  
  <pre><code>./ $autoreconf --install  
  </code></pre>
  
  <ol start="2">
  <li>Can successfully build the project at root directory with using following commands </li>
  </ol>
  
  <pre><code>./ $./configure   
  ./ $make  
  </code></pre>
  
  <ol start="3">
  <li>Get error when building in directory ./build. Commands are:</li>
  </ol>
  
  <pre><code>./build/ $../configure   
  ./build/ $make 
  </code></pre>
  
  <p>Got an error as below image shows:  </p>
  
  <p><a href="https://i.stack.imgur.com/2jlgA.png" rel="nofollow noreferrer">build error image</a></p>
  
  <p>I think this error is caused by the compiler cannot successfully find the header files. My first question is <strong>Why the <code>AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C%</code> in makefile.am cannot solve this problem?</strong></p>
  
  <p>Since the compiler will create the .o files in the build directory with making the build tree has the same subdirectory layout as the source tree. So I can fix this problem by copy the Pet.h file to \build\Pet. However, this means I always need to copy the header files to the build directory, which is not convenient.</p>
  
  <p>I find some info about <a href="https://www.gnu.org/software/automake/manual/html_node/VPATH-Builds.html" rel="nofollow noreferrer">VPATH</a>. So I commented out <code>#VPATH = ./HelloWorld ./Pet</code> in ./HelloWorld/Makefile.am. However, it will give me a new problem:</p>
  
  <p><a href="https://i.stack.imgur.com/tmX4Y.png" rel="nofollow noreferrer">automake error image</a></p>
  
  <p>My assumption is the VPATH setting somehow conflicts with the include makefile.am. My second question is <strong>How can I use the VPATH correctly with using include makefile?</strong></p>