В настоящее время я изучаю, как кодировать без IDE, и поэтому я учусь писать make-файлы. Вот мой текущий тестовый проект:
\__ /CoDstructor/
|\__ Makefile
|\__ /bin/
| \__ CoDstructor.exe
|\__ /src/
| \__ /cod/
| |\__ main.cpp
| |\__ types.cpp
| \__ types.hpp
\__ /obj/
\__ /cod/
|\__ main.o
|\__ main.d
|\__ types.o
\__ types.d
У меня есть только один make-файл верхнего уровня, который обрабатывает каждый модуль в каталоге src/ и создает объекты и файлы зависимостей в каталоге obj/. Вот файлы:
main.cpp
#include <iostream>
#include <cod/types.hpp>
int main() {
int s;
std::cin >> s;
return lol();
}
типы.hpp
#ifndef TYPES_HPP_INCLUDED
#define TYPES_HPP_INCLUDED
int lol();
#endif // TYPES_HPP_INCLUDED
типы.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)
И вот ошибка:
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
Я искал почти два дня, как решить эти ошибки.
Для первого (несколько определений main): я уже проверил переменную OBJS, и она содержит и связывает только один раз main.o. И почему в первой строке написано obj/cod/types.o
? В types.hpp/types.cpp
нет главного.
Вторая ошибка (неопределенная ссылка на lol()): почему ссылка не определена, но вместо этого не дает ошибки компилятора?
Третья ошибка (каждый раз пересобирает все, а не только измененные или вместо поиска файлов зависимостей .d)
Я использую последнюю сборку MinGW32 (g++ 4.9.1) и последнюю версию MSYS (make).
Что я здесь делаю неправильно?
{ "cmd":["make"], "path": "D:/DEV/MinGW/w32/mingw32/bin/;D:/DEV/msys/1.0/bin", "shell": true, }
- person nonsensation   schedule 01.08.2014