title: ld: symbols not found for architecture x86_64
body: <p>and thank you for all help in advance. I am new to C/C++ and am teaching myself by throwing myself in the deep end. I am attempting to write a shared (static? not sure the difference) library and write a simple program to use said library. I am probably not doing this in the most efficient way (if it were Python, I'd be done with this project a week ago) but I am more concerned in knowing what and why I am doing things incorrectly. Again, thank you for all help:</p>
  
  <p>LinAlg.h</p>
  
  <pre><code>//// PROTECT HEADER
  #pragma once
  
  
  //// IMPORT LIBRARIES
  // standard modules
  #include &lt;exception&gt;
  // custom modules
  
  
  
  //// DEFINE OBJECT
  namespace LinAlg
  {
      class ktaArr
      {
      public:
          // INIT
          ktaArr(int w, int h);
          ktaArr(int w, int h, double val);
          // SETTERS
          void SetValue(int row, int col, double val);
          // GETTERS
          int GetWidth();
          int GetHeight();
          double GetValue(int row, int col);
          // METHODS
          ktaArr dot(ktaArr arr2);
          void Display();
          // OPPERATORS
          ktaArr operator=(ktaArr arr2);
          ktaArr operator+(ktaArr arr2);
          ktaArr operator-(ktaArr arr2);
          ktaArr operator*(ktaArr arr2);
          ktaArr operator/(ktaArr arr2);
          // RELATIONS
          bool operator==(ktaArr arr2);
          bool operator&lt;=(ktaArr arr2);
          bool operator&gt;=(ktaArr arr2);
          bool operator!=(ktaArr arr2);
          // DECONSTRUCTOR
          ~ktaArr()
          {
              for(int i = 0; i &lt; h; i++)
              {
                  delete arr[i];
              }
          };
  
      protected:
          int w, h;
          double** arr;
  
      private:
  
  
      };
  }
  
  //// DEFINE EXCEPTION
  namespace LinAlg
  {
      class IllegalArraySize: public std::exception {
      private:
          virtual const char* what() const throw()
          {
              return "Invalid use: array sizes do not match.";
          }
      };
  }
  </code></pre>
  
  <p>LinAlg.cpp</p>
  
  <pre><code>//// IMPORT LIBRARIES
  // standard modules
  #include &lt;iostream&gt;
  // custom modules
  #include "LinAlg.h"
  
  
  ///////////////////////////////////////////////////////////////////////////////
  // INIT
  
  LinAlg::ktaArr::ktaArr(int h, int w)
  {
      LinAlg::ktaArr::w = w;
      LinAlg::ktaArr::h = h;
  //  LinAlg::ktaArr::arr = new double[LinAlg::ktaArr::h][LinAlg::ktaArr::w];
      LinAlg::ktaArr::arr = new double*[LinAlg::ktaArr::h];
      for (int col = 0; col &lt; LinAlg::ktaArr::w; col++)
      {
          LinAlg::ktaArr::arr[col] = new double[LinAlg::ktaArr::w];
      }
  }
  
  LinAlg::ktaArr::ktaArr(int h, int w, double val)
  {
      LinAlg::ktaArr::w = w;
      LinAlg::ktaArr::h = h;
  //  LinAlg::ktaArr::arr = new double[LinAlg::ktaArr::h][LinAlg::ktaArr::w];
      LinAlg::ktaArr::arr = new double*[LinAlg::ktaArr::h];
      for (int col = 0; col &lt; LinAlg::ktaArr::w; col++)
      {
          LinAlg::ktaArr::arr[col] = new double[LinAlg::ktaArr::w];
      }
  
      //iterate over array and set values to val
      for (int row = 0; row &lt; LinAlg::ktaArr::h; row++)
      {
          for (int col = 0; col &lt; LinAlg::ktaArr::w; col++)
          {
              LinAlg::ktaArr::arr[row][col] = val;
          }
      }
  }
  
  // INIT
  ///////////////////////////////////////////////////////////////////////////////
  
  ///////////////////////////////////////////////////////////////////////////////
  // SETTERS
  
  void LinAlg::ktaArr::SetValue(int row, int col, double val)
  {
      if ((row+1 &gt; LinAlg::ktaArr::h) || (col+1 &gt; LinAlg::ktaArr::w))
      {
          throw LinAlg::IllegalArraySize();
      }
      LinAlg::ktaArr::arr[row][col] = val;
  }
  
  // SETTERS
  ///////////////////////////////////////////////////////////////////////////////
  
  ///////////////////////////////////////////////////////////////////////////////
  // GETTERS
  
  int LinAlg::ktaArr::GetWidth()
  {
      return LinAlg::ktaArr::w;
  }
  
  int LinAlg::ktaArr::GetHeight()
  {
      return LinAlg::ktaArr::h;
  }
  
  double LinAlg::ktaArr::GetValue(int row, int col)
  {
      return LinAlg::ktaArr::arr[row][col];
  }
  
  // GETTERS
  ///////////////////////////////////////////////////////////////////////////////
  
  ///////////////////////////////////////////////////////////////////////////////
  // METHODS
  
  LinAlg::ktaArr LinAlg::ktaArr::dot(LinAlg::ktaArr arr2)
  {
      // Check size of arrays first
      if (LinAlg::ktaArr::h != arr2.GetHeight())
      {
          throw LinAlg::IllegalArraySize();
      }
  
      // Create new array
      LinAlg::ktaArr arrNew(LinAlg::ktaArr::h, arr2.GetWidth());
      // Assign each value
      double value;
      for (int row = 0; row &lt; arrNew.GetHeight(); row++)
      {
          for (int col = 0; col &lt; arrNew.GetWidth(); col++)
          {
              value = 0;
              // Perform multiplication
              for (int el = 0; el &lt; w; el++)
              {
                  value += LinAlg::ktaArr::arr[row][el] *
                           arr2.GetValue(el, col);
              }
              arrNew.SetValue(row, col, value);
          }
      }
  
      return arrNew;
  }
  
  void LinAlg::ktaArr::Display()
  {
      for (int row = 0; row &lt; LinAlg::ktaArr::h; row++)
      {
          for (int col = 0; col &lt; LinAlg::ktaArr::w; col++)
          {
              if ((row == 0) &amp;&amp; (col == 0))
              {
                  // first element
                  std::cout &lt;&lt; "[[" &lt;&lt; LinAlg::ktaArr::arr[row][col];
              }
              else if ((row == LinAlg::ktaArr::h-1) &amp;&amp;
                       (col == LinAlg::ktaArr::w-1))
              {
                  // last element
                  std::cout &lt;&lt; ", " &lt;&lt; LinAlg::ktaArr::arr[row][col]
                            &lt;&lt; "]]" &lt;&lt; std::endl;
              }
              else if ((row != 0) &amp;&amp; (col == 0))
              {
                  // first element of row
                  std::cout &lt;&lt; " [" &lt;&lt; LinAlg::ktaArr::arr[row][col];
              }
              else if ((row != LinAlg::ktaArr::h-1) &amp;&amp;
                       (col == LinAlg::ktaArr::w-1))
              {
                  // last element of row
                  std::cout &lt;&lt; ", " &lt;&lt; LinAlg::ktaArr::arr[row][col]
                            &lt;&lt; "]" &lt;&lt; std::endl;
              }
              else
              {
                  // print out value
                  std::cout &lt;&lt; ", " &lt;&lt; LinAlg::ktaArr::arr[row][col];
              }
          }
      }
  }
  
  // METHODS
  ///////////////////////////////////////////////////////////////////////////////
  
  ///////////////////////////////////////////////////////////////////////////////
  // OPPERATORS
  
  LinAlg::ktaArr LinAlg::ktaArr::operator=(LinAlg::ktaArr arr2)
  {
      LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                             arr2.GetWidth());
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              newArr.SetValue(row, col, arr2.GetValue(row,col));
          }
      }
      return newArr;
  }
  
  LinAlg::ktaArr LinAlg::ktaArr::operator+(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                             arr2.GetWidth());
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              newArr.SetValue(row, col,
                              LinAlg::ktaArr::arr[row][col]
                                  + arr2.GetValue(row,col));
          }
      }
      return newArr;
  }
  
  LinAlg::ktaArr LinAlg::ktaArr::operator-(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                             arr2.GetWidth());
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              newArr.SetValue(row, col,
                              LinAlg::ktaArr::arr[row][col]
                                  - arr2.GetValue(row,col));
          }
      }
      return newArr;
  }
  
  LinAlg::ktaArr LinAlg::ktaArr::operator*(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                             arr2.GetWidth());
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              newArr.SetValue(row, col,
                              LinAlg::ktaArr::arr[row][col]
                                  * arr2.GetValue(row,col));
          }
      }
      return newArr;
  }
  
  LinAlg::ktaArr LinAlg::ktaArr::operator/(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                             arr2.GetWidth());
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              newArr.SetValue(row, col,
                              LinAlg::ktaArr::arr[row][col]
                                  / arr2.GetValue(row,col));
          }
      }
      return newArr;
  }
  
  // OPPERATORS
  ///////////////////////////////////////////////////////////////////////////////
  
  ///////////////////////////////////////////////////////////////////////////////
  // RELEATIONS
  
  bool LinAlg::ktaArr::operator==(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              if (LinAlg::ktaArr::arr[row][col] != arr2.GetValue(row, col))
              {
                  return false;
              }
          }
      }
      return true;
  }
  
  bool LinAlg::ktaArr::operator&lt;=(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              if (LinAlg::ktaArr::arr[row][col] &gt;= arr2.GetValue(row, col))
              {
                  return false;
              }
          }
      }
      return true;
  }
  
  bool LinAlg::ktaArr::operator&gt;=(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              if (LinAlg::ktaArr::arr[row][col] &lt;= arr2.GetValue(row, col))
              {
                  return false;
              }
          }
      }
      return true;
  }
  
  bool LinAlg::ktaArr::operator!=(LinAlg::ktaArr arr2)
  {
      if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
          (LinAlg::ktaArr::w != arr2.GetWidth()))
      {
          throw LinAlg::IllegalArraySize();
      }
      for(int row = 0; row &lt; arr2.GetHeight(); row++)
      {
          for(int col = 0; col &lt; arr2.GetWidth(); col++)
          {
              if (LinAlg::ktaArr::arr[row][col] == arr2.GetValue(row, col))
              {
                  return false;
              }
          }
      }
      return true;
  }
  
  // RELATIONS
  ///////////////////////////////////////////////////////////////////////////////
  </code></pre>
  
  <p>main.cpp</p>
  
  <pre><code>//// IMPORT LIBRARIES
  // standard modules
  #include &lt;iostream&gt;
  // custom modules
  #include "../LinAlgLib/LinAlg.h"
  
  int main()
  {
      LinAlg::ktaArr identity (3,3,0.0);
      std::cout &lt;&lt; "Display 3x3 zeros array:" &lt;&lt; std::endl;
      identity.Display();
      std::cout &lt;&lt; "test" &lt;&lt; std::endl;
      return 0;
  }
  </code></pre>
  
  <p>Everything is done on Mac OSX 10.9, using GCC as follows:</p>
  
  <p>LinAlg library</p>
  
  <pre><code>make all 
  Building file: ../LinAlg.cpp
  Invoking: Cross G++ Compiler
  g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"LinAlg.d" -MT"LinAlg.d" -o "LinAlg.o" "../LinAlg.cpp"
  Finished building: ../LinAlg.cpp
  
  Building target: libLinAlg.so
  Invoking: Cross G++ Linker
  g++ -shared -o "libLinAlg.so"  ./LinAlg.o   
  Finished building target: libLinAlg.so
  </code></pre>
  
  <p>Test app (main.cpp):</p>
  
  <pre><code>make all 
  Building file: ../main.cpp
  Invoking: Cross G++ Compiler
  g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
  Finished building: ../main.cpp
  
  Building target: testKyleLinAlg
  Invoking: Cross G++ Linker
  g++  -o "testKyleLinAlg"  ./main.o   
  Undefined symbols for architecture x86_64:
    "LinAlg::ktaArr::ktaArr(int, int, double)", referenced from:
        _main in main.o
    "LinAlg::ktaArr::Display()", referenced from:
        _main in main.o
  ld: symbol(s) not found for architecture x86_64
  collect2: ld returned 1 exit status
  make: *** [testKyleLinAlg] Error 1
  </code></pre>
  
  <p>Thanks again for any/all help.</p>