Having trouble building a simple makefile for my project which uses 1 lib, 7 files and c++11

I’ve read 10-20 articles on Stackoverflow plus the GNU make manual, but none of them explain my situation. Many of the guides talk about abstract hypothetical questions but I just want a quick practical solution. I have 7 files, I must use c++11 and I need to link the -lSDL2 library. Here’s what I’ve got so far:

CC=g++

DEPS = main.cpp graphics.cpp graphics.h input.cpp input.h thing.cpp thing.h




%.o: %.c $(DEPS)
	$(CC) -c -o $@ $< $(CFLAGS)


hellomake: $(OBJ)
	g++ **main.cpp graphics.cpp graphics.h input.cpp input.h thing.cpp thing.h** -o your_program_exe $@ $^ $(CFLAGS)

I’ve kinda hacked it together from various tutorials, it’s hard to make a consistent makefile because there’s 5 different ways to do it, and some guides use stuff which is apparently deprecated. I still don’t know how to add -lSDL2 and actually that isn’t the problem at this stage.

jeff@linux-3bv9:~/noob> make
g++ main.cpp graphics.cpp graphics.h input.cpp input.h thing.cpp thing.h -o your_program_exe hellomake  
g++: error: hellomake: No such file or directory
makefile:10: recipe for target 'hellomake' failed
make: *** [hellomake] Error 1
jeff@linux-3bv9:~/noob>

I don’t even know what the error means and I’ve used Linux since I was a teenager.

In that last line of your makefile, you’re referencing a series of files.
I’m guessing that at least one of them doesn’t exist.
Double check that, you can ls or if necessary tree to display your source tree.

BTW - Although it may not make a difference, my personal rule of thumb to minimize possible compatibility issues is to build on the same system as the output so I can test immediately.

TSU

Noob-A-Tron source:

jeff@linux-3bv9:~/noob> ls -ltotal 24656
-rw-r--r-- 1 jeff users      918 Mar  7 21:06 graphics.cpp
-rw-r--r-- 1 jeff users      410 Mar  7 21:06 graphics.h
-rw-r--r-- 1 jeff users 11928656 Aug  6 19:09 graphics.h.gch
-rw-r--r-- 1 jeff users      805 Mar  7 21:06 input.cpp
-rw-r--r-- 1 jeff users      262 Mar  7 21:06 input.h
-rw-r--r-- 1 jeff users  6630896 Aug  6 19:09 input.h.gch
-rw-r--r-- 1 jeff users     1404 Aug  6 19:40 main.cpp
-rw-r--r-- 1 jeff users     3904 Aug  6 20:04 main.o
-rwxr-xr-x 1 jeff users      241 Aug  6 20:29 makefile
-rw-r--r-- 1 jeff users     1790 Mar  7 21:06 thing.cpp
-rw-r--r-- 1 jeff users      557 Mar  7 21:06 thing.h
-rw-r--r-- 1 jeff users  6647280 Aug  6 19:09 thing.h.gch
jeff@linux-3bv9:~/noob>

Those green highlights are the 7 files so I am sure the problem is somewhere else.

It’s difficult to know what’s best for you without knowing exactly what you’re trying to compile. What you are showing
looks suspiciously Window-based (e.g. *.cpp files and your_program_exe) but otherwise it’s mere guesswork.

If you are trying to compile an executable from C++ files then the makefile job is very simple with two stages:

  1. Compile all each source C++ file to an object.
  2. Link all objects with library dependencies and the main object to create an executable.

If you are compiling a library, it’s a little different but I suspect you are not.

So here’s one useful tutorial with examples:

http://makepp.sourceforge.net/1.19/makepp_tutorial.html

For example, here’s a (completely untested) example generic C++ makefile (the file must be called `makefile’) (for
C++11) compiling src/.cc files using headers contained in include/, and library dependencies in lib/ (which archive
libarchive.a). Object builds are compiled to build/
.o and linked to bin/a.out:


CC := g++
SRCDIR := src
BUILDDIR := build
BINDIR := bin
TARGET := bin/a.out
SRCEXT := cc

SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -std=c++11
LIB := -L lib -larchive
INC := -I include -I build

$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
@mkdir -p $(BUILDDIR)
@echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<"; $(CC) $(CFLAGS) $(INC) -c -o $@ $<

$(TARGET): $(OBJECTS)
@mkdir -p $(BINDIR)
@echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB)

This makefile is based on a template from:

http://hiltmon.com/blog/2013/07/03/a-simple-c-plus-plus-project-structure/

If you want to call your makefile hellomake', you can, _but_ rather than invoking make’ you must invoke `make -f
hellomake’.

The other thing is - do you need as something as sophisticated as make? If you’re just compiling 7 C++ sources and only
linking to -lSDL2 you can shell-script that in two lines e.g.


sh-4.3$ g++ -c -std=c++11 file1.cpp file2.cpp file3.cpp file4.cpp file5.cpp file6.cpp file7.cpp
sh-4.3$ g++ -std=c++11 main.cpp file1.o file2.o file3.o file4.o file5.o file6.o -o executable.run -lSDL2 -L/path/to/libSDL2.object_or_archive

> Code:
> --------------------
> jeff@linux-3bv9:~/noob> make
> g++ main.cpp graphics.cpp graphics.h input.cpp input.h thing.cpp thing.h -o your_program_exe hellomake
> g++: error: hellomake: No such file or directory
> makefile:10: recipe for target ‘hellomake’ failed
> make: *** [hellomake] Error 1
> jeff@linux-3bv9:~/noob>
>
> --------------------

Are you trying to compile the makefile? If so, you need to go back to the tutorials and read them much more slowly. The
makefile is a specification file for what files to compile, how, and where. You can also create specifications for
linking and archiving objects.

HTH.

On 2017-08-08, flymail <flymail@no-mx.forums.microfocus.com> wrote:
> http://makepp.sourceforge.net/1.19/makepp_tutorial.html

…apologies… that tutorial appears to be on makepp.

Holy moly! Thanks for the tutorial on hiltmon - it solved my problem in about 15 minutes. I got a missing separator error so I replaced all double-spaces with a ’ ’ then I created the bin and src files (plus a few others) and I specified my library. This particular makefile method is the best as I don’t have to specify my files in the makefile, it simply grabs them from src without being prompted. My project is only 7 files but I plan to make it much larger. I could make a shell script and use a wildcard to find all my files (now that I think of it) but I wanted to use ‘make’ because I think it’s the most professional way to build a program.

On 2017-08-08, kiwicoder <kiwicoder@no-mx.forums.microfocus.com> wrote:
> Holy moly! Thanks for the tutorial on ‘hiltmon’
<SNIP>
> because I think it’s the most professional way to build a program.

… if you want to be a bit professional, you should probably follow proper makefile conventions. For example, if you’re
compiling C++ rather than C, you should probably use CXXFLAGS rather than CFLAGS. Unfortunately the conventions break
down a little when you code in assembler, but hopefully you don’t have to worry about that…

If I may suggest and/or recommend, try to learn cmake and/or GNU autoconf + automake and use them to automatically generate your Makefile. For cmake, please peruse this CMake Tutorial. Below is a sample CMakeFiles.txt file. All you need is to copy the CMakeFiles.txt to the root directory of your project. For in-source build (not recommended), then issue either “cmake .” or "ccmake ." in the root directory of your project where you put your CMakeFiles to generate your Makefile. The later is a curses based (terminal handling library) UI to cmake and it allows you to manipulate (enable/disable) options to include into generated Makefile file. For out-of-source build (recommended), create a build directory in your root project directory where your CMakeFiles.txt is and change into your newly created build directory. From there you can issue either “cmake …” or "ccmake …" to generate your Makefile file. In out-of-source build, once you run either “cmake …” or "ccmake …", you can subsequently run either “cmake .” or "ccmake ." to regenerate your Makefile.

cmake_minimum_required (VERSION 2.6)
project (hellomake)

# add strip executable for Release version
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

# add -std=c++14 to CXX_FLAGS to comply with C++ 2014 standard
set (CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")

# add executable
add_executable(hellomake main.cpp graphics.cpp graphics.h input.cpp input.h thing.cpp thing.h)

# add the install targets
install (TARGETS hello_class DESTINATION bin)