Im currently learning how to code without an IDE and so Im learning how to write makefiles. Here is my current test-project:
\__ /CoDstructor/
|\__ Makefile
|\__ /bin/
| \__ CoDstructor.exe
|\__ /src/
| \__ /cod/
| |\__ main.cpp
| |\__ types.cpp
| \__ types.hpp
\__ /obj/
\__ /cod/
|\__ main.o
|\__ main.d
|\__ types.o
\__ types.d
I only have one single top level makefile that handles every module in the src/ directory and creates the objects and dependency files in the obj/ directory. Here are the files:
main.cpp
#include <iostream>
#include <cod/types.hpp>
int main() {
int s;
std::cin >> s;
return lol();
}
types.hpp
#ifndef TYPES_HPP_INCLUDED
#define TYPES_HPP_INCLUDED
int lol();
#endif // TYPES_HPP_INCLUDED
types.cpp
#include <iostream>
#include <cod/types.hpp>
int lol() {
std::cout << "lol";
return 0;
}
Makefile
APP_NAME = CoDstructor
DEBUG_TARGET = debug
RELEASE_TARGET = release
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
INC_DIR = src
INCLUDE_DIRS +=
LIBRARY_DIRS +=
CXXFLAGS += -Wall
CXXFLAGS += -Werror
CXXFLAGS += -Wextra
CXXFLAGS += -pedantic
CXXFLAGS += -std=c++11
$(DEBUG_TARGET): CXXFLAGS += -g
$(RELEASE_TARGET): CXXFLAGS += -O3
LDFLAGS += -static
LDFLAGS += -static-libstdc++
LDFLAGS += -static-libgcc
$(DEBUG_TARGET): LDFLAGS += -g
$(RELEASE_TARGET): LDFLAGS +=
CPPMACROS =
$(DEBUG_TARGET): CPPMACROS += DEBUG
$(RELEASE_TARGET): CPPMACROS += NDEBUG
CXXFLAGS += $(foreach i,$(INC_DIR),$(addprefix -I,$(i)))
CXXFLAGS += $(foreach i,$(INCLUDE_DIRS),$(addprefix -I,$(i)))
CXXFLAGS += $(foreach i,$(CPPMACROS),$(addprefix -D,$(i)))
LIBS = $(foreach i,$(LIBRARY_DIRS),$(addprefix -L,$(i)))
SOURCES = $(subst ./,,$(shell find . -name *.cpp))
OBJS = $(subst $(SRC_DIR),$(OBJ_DIR),$(SOURCES:.cpp=.o))
DEPS = $(OBJS:.o=.d)
all: $(DEBUG_TARGET) clean
$(RELEASE_TARGET): $(BIN_DIR)/$(APP_NAME) clean
@echo Building release...
$(DEBUG_TARGET): $(BIN_DIR)/$(APP_NAME) clean
@echo Building debug...
$(OBJS): $(SOURCES)
@mkdir -p $(@D)
$(CXX) -MMD -MP $(CXXFLAGS) -c $< -o $@
$(BIN_DIR)/$(APP_NAME): $(OBJS)
$(CXX) $(LDFLAGS) $^ -o $@ $(LIBS)
@echo $^
.PHONY: clean
clean:
@echo clean
# @-rmdir $(OBJ_DIR)
-include $(DEPS)
And here is the error:
obj/cod/types.o: In function `main':
D:\PROJECTS\CoDstructor/src/cod/main.cpp:4: multiple definition of `main'
obj/cod/main.o:D:\PROJECTS\CoDstructor/src/cod/main.cpp:4: first defined here
obj/cod/main.o:main.cpp:(.text+0x2a): undefined reference to `lol()'
obj/cod/types.o:main.cpp:(.text+0x2a): undefined reference to `lol()'
collect2.exe: error: ld returned 1 exit status
I searched for almost two days now how to resolve these errors.
For the first one (multiple definitions of main):
I already checked the OBJS variable, and it contains and links only one time the main.o. Also why says it obj/cod/types.o
in the first line? There is no main in types.hpp/types.cpp
.
The second error (undefined reference to lol()): Why is the reference undefined, but gives no compiler error instead?
The third error (it rebuilds everything everytime, instead of only changed ones or instead of looking up the .d dependency files)
I am running the latest MinGW32 build (g++ 4.9.1) and latest MSYS (make).
What am I doing wrong here?