Как правильно использовать флаг -MD в Makefile - PullRequest
0 голосов
/ 24 ноября 2018

Я пытаюсь создать 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;
}

1 Ответ

0 голосов
/ 26 ноября 2018

Проблема заключалась в том, что я постоянно копировал заголовки библиотеки в /usr/local, поэтому файлы становились все новее, и клиент make думал, что каждый заголовок библиотеки изменился.

Простым решением этой проблемы было заменить в файле Makefile библиотеки следующую строку:

sudo rm -rf /usr/local/include/test_lib && sudo cp -r $(INC_FOLDER) /usr/local/include/test_lib

на

sudo rm -rf /usr/local/include/test_lib && sudo ln -s $(CUR_DIR)/$(INC_FOLDER) /usr/local/include/test_lib

В дополнительном примечании в приведенном примере отсутствует удаление файлов .d в чистом правиле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...