Я пытаюсь создать Makefile, где make только перекомпилирует необходимые .cpp
файлы.
По умолчанию, он работает хорошо, если я редактирую .cpp
, однако, когда я редактирую .h
файлы,он просто игнорирует изменения.
Так что я прочитал флаг -MD
и его друга -MP
(используется, чтобы избежать ошибок при вводе make).
Однако я не могуКажется, он работает, если я использую -MMD
, он работает отлично, но я полагаюсь и на системные включения, так как я пишу библиотеку, которая развивается вместе с проектом.Таким образом, если я обновляю заголовок библиотеки и переустанавливаю библиотеку, ввод make
в основном проекте должен перекомпилировать файлы, которые содержат измененный заголовок.
При использовании флага -MMD
он, как и ожидалось, не выполняетперекомпилируйте проект, однако, используя флаг -MD
, он все перекомпилирует.Фактически, -MD
перекомпилирует все каждый раз, даже когда ничего не изменилось.
Вот минимальная структура проекта, которая воспроизводит проблему:
. / Makefile:
all: build
re: clean build
build: build_lib install_lib build_client
build_lib:
$(MAKE) -C lib
$(MAKE) install -C lib
build_client:
$(MAKE) -C client
install_lib:
$(MAKE) install -C lib
.PHONY: clean
clean: clean_lib clean_client
clean_lib:
$(MAKE) clean -C lib
clean_client:
$(MAKE) clean -C client
. / Client / Makefile:
CC = g++
INC = -I../lib
CXXFLAGS = -Wall $(INC) -g -MD -MP
EXEC_NAME = ../test
src = $(shell find $(SOURCEDIR) -name '*.cpp')
obj = $(src:.cpp=.o)
LIBRARIES = -ltest_lib
LDFLAGS = -rdynamic $(LIBRARIES)
all: $(EXEC_NAME)
re: clean $(EXEC_NAME)
$(EXEC_NAME): $(obj)
$(CC) -o $@ $^ $(LDFLAGS)
-include $(obj:.o=.d)
.PHONY: clean
clean:
rm -f $(obj) $(EXEC_NAME)
. / Lib / Makefile:
.PHONY : clean
CXXFLAGS= -fPIC -g -Itest_lib/include -MMD -MP
LDFLAGS= -shared
SOURCES = $(shell find $(SOURCEDIR) -name '*.cpp')
HEADERS = $(shell find $(SOURCEDIR) -name '*.h')
OBJECTS=$(SOURCES:.cpp=.o)
TARGET=libtest_lib.so
INC_FOLDER=test_lib/include
CUR_DIR = $(shell pwd)
all: $(TARGET)
install:
sudo rm -rf /usr/local/lib/libtest_lib.so && sudo ln -s $(CUR_DIR)/$(TARGET) /usr/local/lib/libtest_lib.so
sudo rm -rf /usr/local/include/test_lib && sudo cp -r $(INC_FOLDER) /usr/local/include/test_lib
clean:
rm -f $(OBJECTS) $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $@ $(LDFLAGS)
-include $(OBJECTS:.o=.d)
. / Client / main.cpp:
#include "bar.h"
int main()
{
Bar b;
b.sayHello();
b.sayBye();
return 0;
}
./client/bar.h
#ifndef __BAR__
#define __BAR__
#include <test_lib/foo.h>
#include <iostream>
struct Bar : public Foo
{
Bar() {};
~Bar() {};
void sayBye() const {
std::cout << "Bye " << name << "..." << std::endl;
};
};
#endif
. / lib / test_lib / include / foo.h
#ifndef __FOO__
#define __FOO__
struct Foo
{
const char *name;
Foo(const char *name = "world");
~Foo();
void sayHello() const;
};
#endif
. / lib / test_lib / src
#include "foo.h"
#include <iostream>
Foo::Foo(const char *name) : name(name) {}
Foo::~Foo() {}
void Foo::sayHello() const
{
std::cout << "Hello " << name << " !" << std::endl;
}