title: Program won't compile with makefile, but works without it
body: <p>I'm just learning SDL and have finished the <a href="http://twinklebear.github.io/sdl2%20tutorials/2013/08/15/lesson-0-linux-command-line/" rel="nofollow">twinklebear tutorials</a>.  After I began splitting the code into multiple files, my makefile stopped working and I had to compile it manually.  It says:</p>
  
  <pre><code>make: *** No rule to make target `main.o', needed by `ooptest'.  Stop.
  </code></pre>
  
  <p>when I use a rule like <code>.cxx.o:</code>, or, if I make separate rules for all of my <code>.cxx</code>'s:</p>
  
  <pre><code>g++ main.o -L/usr/local/lib -lSDL2 -Wl,-rpath=/usr/local/lib -o ooptest
  main.o: In function `main':
  main.cxx:(.text+0x247): undefined reference to `init(SDL_Window**, SDL_Renderer**)'
  main.cxx:(.text+0x42e): undefined reference to `quit(SDL_Window**, SDL_Renderer**)'
  collect2: error: ld returned 1 exit status
  make: *** [ooptest] Error 1
  </code></pre>
  
  <p>I know this is because it's only linking main.o and none of the other files but I don't know why.</p>
  
  <p>Here are the 7 relevant files (just skip these unless they help resolve the problem, I don't know how to make them inside a spoiler or something):
  makefile:</p>
  
  <pre><code>CXX         = g++
  SRCS        = main.cxx init.cxx quit.cxx
  SDL_LIB     = -L/usr/local/lib -lSDL2 -Wl,-rpath=/usr/local/lib
  SDL_INCLUDE = -I/usr/local/include
  CXXFLAGS    = -Wall -c -std=c++11 $(SDL_INCLUDE)
  LDFLAGS     = $(SDL_LIB)
  OBJS        = $(SRCS:.cxx=.o)
  EXE         = ooptest
  all: $(EXE) $(SRCS)
  $(EXE): $(OBJS)
      $(CXX) $&lt; $(LDFLAGS) -o $@
  main.o:
      $(CXX) $(CXXFLAGS) main.cxx -o $@
  init.o:
      $(CXX) $(CXXFLAGS) init.cxx -o $@
  quit.o:
      $(CXX) $(CXXFLAGS) quit.cxx -o $@
  #.cxx.o:
  #   $(CXX) $(CXXFLAGS) $&lt; -o $@
  clean:
      rm *.o &amp;&amp; rm $(EXE)
  </code></pre>
  
  <p>main.h:</p>
  
  <pre><code>#ifndef _MAIN_
  #define _MAIN_
  #include &lt;string&gt;
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  const int WIDTH=640;
  const int HEIGHT=480;
  void lgErr(std::string);
  SDL_Texture*loadTex(const std::string&amp;,SDL_Renderer*);
  void renderTex(SDL_Texture*,SDL_Renderer*,int,int);
  int main(void);
  #endif
  </code></pre>
  
  <p>main.cxx:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  #include "main.h"
  #include "init.h"
  #include "quit.h"
  
  using namespace std;
  
  void lgErr(string msg){
      cout&lt;&lt;msg&lt;&lt;" error: "&lt;&lt;SDL_GetError()&lt;&lt;endl;
  }
  
  SDL_Texture* loadTex(const string &amp;file,SDL_Renderer *ren){
      SDL_Texture *tex=0;
      SDL_Surface *img=SDL_LoadBMP(file.c_str());
      if(img){
          tex=SDL_CreateTextureFromSurface(ren,img);
          SDL_FreeSurface(img);
          if(tex==0)lgErr("CreateTextureFromSurface");
      }else
          lgErr("LoadBMP");
      return tex;
  }
  
  void renderTex(SDL_Texture *tex,SDL_Renderer *ren,int x,int y){
      SDL_Rect dst;
      dst.x=x;dst.y=y;
      SDL_QueryTexture(tex,NULL,NULL,&amp;dst.w,&amp;dst.h);
      SDL_RenderCopy(ren,tex,NULL,&amp;dst);
  }
  
  int main(){
      SDL_Window *win;
      SDL_Renderer *ren;
      init(&amp;win,&amp;ren);
      SDL_Texture *bg=loadTex("bg.bmp",ren);
      SDL_Texture *fg=loadTex("fg.bmp",ren);
      if(bg==0 || fg==0)return 4;
      int bw,bh;
      SDL_QueryTexture(bg,NULL,NULL,&amp;bw,&amp;bh);
      SDL_RenderClear(ren);
      for(int i=0;i&lt;WIDTH;i+=bw)
          for(int j=0;j&lt;HEIGHT;j+=bh)
              renderTex(bg,ren,i,j);
      int fw,fh;
      SDL_QueryTexture(fg,NULL,NULL,&amp;fw,&amp;fh);
      int x=WIDTH/2-fw/2;
      int y=HEIGHT/2-fh/2;
      renderTex(fg,ren,x,y);
      SDL_RenderPresent(ren);
      SDL_Delay(2000);
      SDL_DestroyTexture(bg);
      SDL_DestroyTexture(fg);
      quit(&amp;win,&amp;ren);
  }
  </code></pre>
  
  <p>init.h:</p>
  
  <pre><code>#ifndef _INIT_
  #define _INIT_
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  int init(SDL_Window**,SDL_Renderer**);
  #endif
  </code></pre>
  
  <p>init.cxx:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  #include "main.h"
  #include "quit.h"
  
  using namespace std;
  
  int init(SDL_Window** win,SDL_Renderer** ren){
      if(SDL_Init(SDL_INIT_EVERYTHING)!=0){
          lgErr("SDL_Init");
          return 1;
      }
      *win=SDL_CreateWindow("Lesson 2",100,100,WIDTH,HEIGHT,SDL_WINDOW_SHOWN);
      if(*win==0){
          lgErr("CreateWindow");
          return 2;
      }
      *ren=SDL_CreateRenderer(*win,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
      if(*ren==0){
          lgErr("CreateRenderer");
          return 3;
      }
      return 0;
  }
  </code></pre>
  
  <p>quit.h:</p>
  
  <pre><code>#ifndef _QUIT_
  #define _QUIT_
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  void quit(SDL_Window**,SDL_Renderer**);
  #endif
  </code></pre>
  
  <p>quit.cxx:</p>
  
  <pre><code>#include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  #include "main.h"
  #include "init.h"
  
  void quit(SDL_Window** win,SDL_Renderer** ren){
      SDL_DestroyRenderer(*ren);
      SDL_DestroyWindow(*win);
      SDL_Quit();
  }
  </code></pre>
  
  <p>Finally, I'm using <code>GNU Make 3.81</code>, <code>g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3</code>, and SDL2 with the image library.</p>
  
  <p>What is wrong with the makefile rule for .cpp.o and the rule for $(EXE)?  Also, am I using #include properly?</p>