cant make my makefile work - c++

Folder structure of project:
|--particle-system
| |-- bin
| | |-- .o files
| |-- docs
| | |-- design.md
| | `-- TO_DO
| |-- Makefile
| |-- src
| | |-- .cpp files + .h files
| `-- test
I need to put all my .o files generated into the bin folder. Also cleanup should remove all .o files and the /bin folder.
My makefile:
# particle-system Makefile
EXE = particlesystem
OBJ_DIR = bin
CFLAGS = -g
CXXFLAGS = -Wall -Wextra -g -std=c++0x
LDFLAGS = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lSDL2_gfx -lm
# c++ source files of the project
CXXFILES = $(shell find src -maxdepth 1 -type f -name '*.cpp')
CXXOBJ = $(CXXFILES:.cpp=.o)
ifdef V
MUTE =
VTAG = -v
else
MUTE = #
endif
all: $(EXE)
# build successful
$(EXE): $(CXXOBJ)
$(MUTE)$(CXX) $(CXXOBJ) -o $(EXE) $(LDFLAGS)
$(OBJ_DIR)/%.o: src/%.cpp
$(MUTE)$(CXX) $(CXXFLAGS) $(INCLUDE) $< -c -o $#
$(OBJ_DIR)/%.o: src/%.c
$(MUTE)$(CC) $(CFLAGS) $(INCLUDE) $< -c -o $#
run: all
$(MUTE)./$(EXE)
clean:
# Cleaning...
-$(MUTE)rm -f $(EXE) $(OBJECTS)
I dont know why this makefile isn't working. Please tell whats wrong here.

This line will cause the .o files to be created in the same directory as the source files:
CXXOBJ = $(CXXFILES:.cpp=.o)
Consequently, these lines have no effect, because there are no .o files in $(OBJ_DIR):
$(OBJ_DIR)/%.o: src/%.cpp
$(MUTE)$(CXX) $(CXXFLAGS) $(INCLUDE) $< -c -o $#
$(OBJ_DIR)/%.o: src/%.c
$(MUTE)$(CC) $(CFLAGS) $(INCLUDE) $< -c -o $#
Also, $(INCLUDE) isn't defined.
In this line, $(OBJECTS) isn't defined:
-$(MUTE)rm -f $(EXE) $(OBJECTS)

Related

Place object files in particular directory with make

I've been looking into building cpp applications with make and looking at various sources online. While it works, I'm trying to build my object files and place those into a particular directory rather then have them go into the same src/ as my source files. Ideally, I would like them to go into the OUT_O_DIR location, but they're being generated and placed in the src/, which I don't want.
I want a structure like this:
.
|- Makefile
|- include/
| |- *.h
|- src/
| |- *.c
|- output/
| |- App
|- obj/
| |- *.o
My make version:
GNU Make 4.1
Built for x86_64-pc-linux-gnu
My Makefile:
OUT_O_DIR := $(OUT_DIR)/obj
PROJ = hello
SOURCE = $(wildcard src/*.cpp)
INC = $(wildcard include/*.h)
OBJS = $(SOURCE:.cpp=.o)
CFLAGS = -I include
CC = g++
.PHONY: directories
all : directories $(OUT_DIR)$(PROJ)
directories: $(OUT_DIR)
$(OUT_DIR)$(PROJ) : $(OBJS)
$(CC) -o $# $(OBJS)
.cpp.o: $(INC)
#echo $#
$(CC) -c $(CFLAGS) $< -o $#
clean :
rm -rf $(OUT_DIR)
$(OUT_DIR):
mkdir -p $(OUT_DIR)
The '.cpp.o' does not extend to cover multiple folders. Two options
Modify OBJS and rule to build object.
#OBJS = $(SOURCE:.cpp=.o)
OBJS = $(SOURCE:src/%.cpp=$(OUT_O_DIR)/%.o)
...
#.cpp.o: $(INC)
${OUT_O_DIR}/%.o: src/%.cpp $(INC)
$(CC) -c $(CFLAGS) $< -o $#
Or use vpath to specify the .cpp files are in src
#OBJS = $(SOURCE:.cpp=.o)
OBJS = $(SOURCE:src/%.cpp=$(OUT_O_DIR)/%.o)
vpath %.cpp src
${OUT_O_DIR}/%.o: %.cpp $(INC)
$(CC) -c $(CFLAGS) $< -o $#

Makefile: no rule to make target: how to set the correct rules?

I have a project that I am trying to create a Makefile for. The folder structure looks like this:
|-- bin
|-- build
|-- Makefile
|-- src
| |-- some_files.cpp
| |-- some_files.h
| |-- ForestFactory
| |-- MMParSet
| |-- century
| |-- century_carbon.cpp
| |-- century_carbon.h
| `-- grass
`-- src_multithread
|-- __history
and I have tried to use this reference to create a Makefile.
The Makefile I have is
CC := g++
SRCDIR := src
BUILDDIR := build
TARGETDIR := bin
INSTALLBINDIR := /usr/local/bin
TARGET := bin/formind
# CPP files
SOURCES := $(shell find $(SRCDIR) -type f -name *.cpp)
# remove the src path and add the build path and the .o extension
OBJECTS := $(addprefix $(BUILDDIR)/,$(patsubst %.cpp,%.o,$(notdir $(SOURCES))))
CFLAGS := -std=c++11 -stdlib=libc++
INC := -I/usr/local/include -I $(SRCDIR) -I $(SRCDIR)/century -I $(SRCDIR)/grass -I $(SRCDIR)/MMParSet -I $(SRCDIR)/ForestFactory
$(TARGET): $(OBJECTS)
#mkdir -p $(TARGETDIR)
#echo " Linking..."
#echo " $(CC) $^ -o $(TARGET)"
$(CC) $^ -o $(TARGET)
$(BUILDDIR)/%.o: $(SRCDIR)/%.cpp
#mkdir -p $(BUILDDIR)
#echo " $(CC) $(CFLAGS) $(INC) -c -o $# $<"
$(CC) $(CFLAGS) $(INC) -c -o $# $<
clean:
#echo " Cleaning...";
#echo " $(RM) -r $(BUILDDIR) $(TARGET)"
$(RM) -r $(BUILDDIR) $(TARGET)
.PHONY: clean
When I try to make I get the following error message:
make: *** No rule to make target `build/century_carbon.o', needed by `bin/formind'. Stop.
The source files come from a nested set of subdirectories inside src. My understanding was that the OBJECTS variable should contain the complete paths of the final object files, so that I have something like
$SOURCES = src/century/century_carbon.cpp ... src/for_branching.cpp ... src/grass/grass_log.cpp ...
$OBJECTS = build/century_carbon.o ... build/for_branching.o ... build/grass_log.o ...
Is there something wrong in the way I wrote the compilation rules?
The problem is with the nested source directory century. If you add to the makefile:
info:
#echo " Info..."
#echo " SOURCES = $(SOURCES)"
#echo " OBJECTS = $(OBJECTS)"
then make info gives:
Info...
SOURCES = src/century/century_carbon.cpp src/some_files.cpp
OBJECTS = build/century_carbon.o build/some_files.o
This check shows that your construction of these macros is ok. And it also shows, as you report, that make will then tell us:
make: *** No rule to make target 'build/century_carbon.o', needed by 'bin/formind'. Stop.
If you add an additional rule, with the directory century specified:
$(BUILDDIR)/%.o: $(SRCDIR)/century/%.cpp
#mkdir -p $(BUILDDIR)
$(CC) $(CFLAGS) $(INC) -c -o $# $<
then your build will proceed.
An alternative solution is to use VPATH. Add the line:
VPATH = src:src/century
and also remove $(SRCDIR)/ from your rule, which now becomes:
$(BUILDDIR)/%.o: %.cpp
#mkdir -p $(BUILDDIR)
$(CC) $(CFLAGS) $(INC) -c -o $# $<
Update: The above answer could be improved in two ways:
Use vpath rather than VPATH, for more precise control of the searches.
Automatically generate the argument for vpath / VPATH.
This is suprisingly simple: just replace my hard-coded VPATH line with:
vpath %.cpp $(sort $(dir $(SOURCES)))

How to write make files with auto dependancy generator

In expansion to my previous question how to write a makefile for structured file system:
The file structure:
.
├── Headers
│   ├── function.h
│   └── test.h
├── makefile
├── README.md
└── Sources
├── function.c
├── main.c
└── test.c
I'm trying to write a makefile that reads the #include<...> on any given source file and compile as required.
Originally I used to have a make file that looked like this:
INC_DIR = Headers
SRC_DIR = Sources
OBJ_DIR = Objects
#CXXFLAGS = -c -Wall -I. -IHeaders
CXXFLAGS = -c -Wall -I. -IHeaders
CC = gcc
SRCS = $(SRC_DIR)/*.c
OBJS = $(OBJ_DIR)/*.o
#The wildcard and patsubt commads will come handy
DEPS = $(INC_DIR)/*.h
#need to use an automatic dependency generator
output: $(OBJ_DIR)/main.o $(OBJ_DIR)/function.o
$(CC) $^ -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS)
$(CC) $(CXXFLAGS) $< -o $#
run: output
./output
clean:
rm $(OBJ_DIR)/*.o
rm output
-#echo "Clean completed"
That meant that for every source file that output was dependent on i had to add that object to this line.
output: $(OBJ_DIR)/main.o $(OBJ_DIR)/function.o $(OBJ_DIR)/test.o
$(CC) $^ -o $#
And is any other source file was dependent on one or more sources additional rules had to be added.
To solve this:
here is what I have gathered from Auto-Dependency Generation and 4.14 Generating Prerequisites Automatically
As mentioned by the community members, I have a mixed understanding of dependency generation and how to make use of the files generated.
DEP_DIR = .d
$(shell mkdir -p $(DEP_DIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEP_DIR)/$*.Td
INC_DIR = Headers
SRC_DIR = Sources
OBJ_DIR = Objects
$(shell mkdir -p $(OBJ_DIR) >/dev/null)
CXXFLAGS = -c -Wall -I. -IHeaders
CC = gcc
SRCS = $(SRC_DIR)/*.c
OBJS = $(OBJ_DIR)/*.o
#The wildcard and patsubt commads will come handy
#DEPS = $(INC_DIR)/*.h
MAKEDEPEND = $(CC) $(CXXFLAGS) $< \
| sed -n 's/^\# *[0-9][0-9]* *"\([^"]*\)".*/$*.o: \1/p' \
| sort | uniq > $*.Td
COMPILE.c = $(CC) $(DEPFLAGS) $(CXXFLAGS)
#need to use an automatic dependency generator
#%.d: %.c
# #set -e; rm -f $#; \
# $(CC) -MP -MD $(CXXFLAGS) $< > $#.$$$$; \
# sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
# rm -f $#.$$$$
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEP_DIR)/%.d
#$(MAKEDEPEND); \
cp $*.Td $*.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.Td >> $*.d; \
rm -f $*.Td
#$(COMPILE.c) -o $# $<
$(CC) $(CXXFLAGS) $(DEPFLAGS) $< -o $#
-include $(SRCS:.c=.d)
$(DEP_DIR)/%.d: ;
.PRECIOUS: $(DEP_DIR)/%.d
output: $(OBJS)
$(CC) $^ -o $#
run: output
./output
clean:
rm -r $(OBJ_DIR)
rm -r $(DEP_DIR)
rm output
-#echo "Clean completed"
The error when make is executed is:
$ make
gcc -c -Wall -I. -IHeaders -MT Objects/*.o -MMD -MP -MF .d/*.Td Sources/function.c -o Objects/*.o
gcc Objects/*.o -o output
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:48: recipe for target 'output' failed
make: *** [output] Error 1
So, I'm hoping to achieve the auto dependency detection and compilation. I think the error is in the way that the dependencies are detected and the way they are generated for a given source file.
It looks to me like you're trying to combine multiple different ways of generating dependency info, and that can't work. The advanced post talks about multiple ways to solve the problem: you need to pick one not try to use them all together.
If you want to use the advanced method then use it as described in the "TL;DR" section at the top, or else in the "Combining Compilation and Dependency Generation" section at the bottom. If you're using GCC there's no need for MAKEDEPEND, sed, etc.
The advanced post says that your rule should look like this:
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
%.o : %.c
%.o : %.c $(DEPDIR)/%.d
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
That's it.

-I flag in the makefile does not result in a header file being found (gtest/gtest.h)

Previously I was struggling with creating a makefile in root directory that would deal with source files being in src folder and headers in include folder. Following this I wanted to add another folder tests where I would keep .cpp files with tests. Unfortunately I have problems with this.
The folder structure is:
.
|__makefile
|
|__/src
| |
| |__[regular .cpp files]
|
|__/include
| |
| |__[.h files]
| |
| |__/gtest
| |
| |__gtest.h
|
|__/tests
|
|__test_factorial.cpp
./tests/test_factorial.cpp:
#include "gtest/gtest.h"
#include "factorial.h"
// some tests
makefile:
CC = g++
CFLAGS = -Wall
INCLUDES = -I./include
LIBS = -lgtest -lpthread
SOURCEDIR = ./src/
SRCS = $(shell find ./src/ -name '*.cpp')
SRCS += $(shell find ./tests/ -name '*.cpp')
.PHONY: clean depend
SRCS := $(filter-out ./tests/main_tests.cpp, $(SRCS))
OBJS = $(SRCS:.cpp=.o)
OBJS := $(OBJS:./src%=.%)
release: $(OBJS)
$(CC) $(CFLAGS) -o app $(OBJS) $(LIBS)
VPATH = ./src:./tests
%.o: ./src/%.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c ./src/$*.cpp
%.o: ./tests/%.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c ./tests/$*.cpp
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) $(INCLUDES) -MM $^ > ./.depend;
include .depend
When I execute make from the root directory all the files from /src compile fine (I end up having object files in the root directory for them) but I get an error for .cpp file from /tests directory:
g++ -c -o tests/test_factorial.o tests/test_factorial.cpp
tests/test_factorial.cpp:1:25: fatal error: gtest/gtest.h: No such file or directory
compilation terminated.
<builtin>: recipe for target 'tests/test_factorial.o' failed
make: *** [tests/test_factorial.o] Error 1
What might be important, the .depend file seems to have it all right:
test_factorial.o: tests/test_factorial.cpp include/gtest/gtest.h \
include/factorial.h
What is wrong with the makefile?
EDIT
I believe this fragment of the error:
<builtin>: recipe for target 'tests/test_factorial.o' failed
suggests that something is wrong in this part of the makefile:
%.o: ./src/%.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c ./src/$*.cpp
%.o: ./tests/%.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c ./tests/$*.cpp
Why it's trying to do ./tests/test_factorial.o rather than ./test_factorial.o? Let me underline again that object files for ./src/*.cpp files end up in root directory, i.e. ./*.o, not ./src/*.o.
Your makefile is building
tests/test_factorial.o
from
tests/test_factorial.cpp
and that doesn't match the rule
%.o: ./tests/%.cpp
So it is instead using a builtin rule. (As an aside, the convention is to build c++ files using $(CXX) and $(CXXFLAGS) not $(CC)).
Try a rule pattern of
./tests/%.o: ./tests/%.cpp
The reason that your Makefile uses the name tests/test_factorial.o is because
OBJS = $(SRCS:.cpp=.o)
which (it should be obvious) makes the path to the .o file the same as the path to the .cpp.
You have a subsequent rule stripping the path src/
OBJS := $(OBJS:./src%=.%)
and no similar rule for tests/

Makefile in the Root Directory of a Project "no Input Files"

I'm having issues getting my Makefile to work for a simple C++ project.
The error I am getting is
"fatal-error: no input files"
Here is my project structure:
ROOT
|
|___Makefile
|
|___bin
|
|___src
| |
| |___main.cpp
|
|___include
|
|___GL
| |
| |___glew.h
| |___glfw3.h
|
|___glm
|
|___glm.hpp
And Here is my Makefile:
CC = g++
INC_DIR1 = include/GL
INC_DIR2 = include/glm
SRC_DIR = src
OBJ_DIR = bin
CFLAGS = -c -Wall -I
SRCS = $(SRC_DIR)/main.cpp
OBJS = $(OBJ_DIR)/main.o
DEPS = $(INC_DIR1)/glew.h $(INC_DIR1)/glfw3.h $(INC_DIR2)/glm.hpp
EXECUTABLE = game
all: $(OBJS) $(EXECUTABLE)
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
$(CC) $(CFLAGS) $< -o $#
$(EXECUTABLE): $(OBJS)
$(CC) $(OBJS) -o $#
$(OBJ_DIR)/main.o: $(DEPS)
I'm not sure if its trying to find .ccp files for the header files or If I set my Makefile up incorrectly. I'm pretty new to Makefiles so any insight would be much appreciated.
Thanks.
EDIT:
So I was able to resolve most of the issues I was having however now I am getting the following error when I try to make my program via command line:
:multiple definition of `main'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../..\libmingw32.a(main.o):main.c:(.tex
t.startup+0x0): first defined here
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../..\libmingw32.a(main.o):main.c:(.tex
t.startup+0xa7): undefined reference to `WinMain#16'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: c:/mingw/b
in/../lib/gcc/mingw32/4.8.1/../../..\libmingw32.a(main.o): bad reloc address 0x2
0 in section `.eh_frame'
collect2.exe: error: ld returned 1 exit status
make: *** [game.exe] Error 1
Below is my Updated Makefile
#Makefile
CC = g++
INC_DIR = include
LIB_DIR = lib
SRC_DIR = src
OBJ_DIR = bin
CFLAGS = -Wall -I $(INC_DIR)
LDFLAGS = -L $(LIB_DIR) -static -lglfw3 -lmingw32
OPTIONS = -std=c++0x -O3
SRCS = $(SRC_DIR)/main.cpp
OBJS = $(OBJ_DIR)/main.o
EXECUTABLE = game.exe
all: $(EXECUTABLE)
$(EXECUTABLE) : $(SRCS)
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $#
clean:
rm $(EXECUTABLE)
I know the issue is that it is finding two main methods in a file somewhere in my mingw32 library but I am unsure as to how I should go about resolving the error.
Please show the command that was invoked and the exact error you got, cut and pasted. It would have taken me about 1/20th the time to see what was wrong if you'd have done that.
Here's your problem:
CFLAGS = -c -Wall -I
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
$(CC) $(CFLAGS) $< -o $#
Expanded out, this will run the following command:
g++ -c -Wall -I src/main.cpp -o bin/main.o
The problem here is you've got -I in your CFLAGS, with no directory after it. That means that the next word, in this case src/main.cpp, is taken to be the directory to be added to the include line.
Probably you want something like:
CFLAGS = -c -Wall -I$(INC_DIR1) -I$(INC_DIR2)